尚硅谷Redis6从入门到精通(下)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介: 尚硅谷Redis6从入门到精通

6. Redis6新数据类型


1. Bitmaps


  1. 合理使用操作位可以有效地提高内存使用率和开发使用率


  1. 本身是一个字符串,不是数据类型,数组的每个单元只能存放0和1,数组的下标在Bitmaps叫做偏移量


  1. 节省空间,一般存储活跃用户比较多



127.0.0.1:6379> setbit users:20210101 1 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 6 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 11 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 15 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 19 1
(integer) 0
127.0.0.1:6379> getbit users:20210101 0
(integer) 0
127.0.0.1:6379> getbit users:20210101 1
(integer) 1
127.0.0.1:6379> bitcount users:20210101
(integer) 5


取交集(按位与):


2020-11-04日访问网站的userid=1,2,5,9


2020-11-03日访问网站的userid=0.1.4.9


127.0.0.1:6379> setbit unique:users:20201104 1 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201104 2 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201104 5 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201104 9 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 0 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 1 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 4 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 9 1
(integer) 0
127.0.0.1:6379> bitop and unqiue:users:and:20201104_03 setbit unique:users:20201103 setbit unique:users:20201104
(integer) 2


2. HyperLogLog


  1. 统计网页中页面访问量


  1. 只会根据输入元素来计算基数,而不会储存输入元素本身,不能像集合那样,返回输入的各个元素


  1. 基数估计是在误差可接受的范围内,快速计算(不重复元素的结算)


127.0.0.1:6379> pfadd program "java"
(integer) 1
127.0.0.1:6379> pfadd program "php"
(integer) 1
127.0.0.1:6379> pfadd program "java"   //重复元素不添加
(integer) 0
127.0.0.1:6379> pfadd program "java" "c++" "mysql"
(integer) 1
127.0.0.1:6379> pfcount program
(integer) 4


127.0.0.1:6379> pfadd k1 "a" "b"
(integer) 1
127.0.0.1:6379> pfcount k1
(integer) 2
127.0.0.1:6379> pfadd k2 "1" "11" "111"
(integer) 1
127.0.0.1:6379> pfcount k2 
(integer) 3
//合并
127.0.0.1:6379> pfmerge kres k1 k2
OK
127.0.0.1:6379> pfcount kres
(integer) 5


3. Geospatial


提供经纬度设置,查询范围,距离查询等


两极无法直接添加,有效的经度从-180到180度;有效的纬度从-85.05112878到85.05112878度


//插入数据
127.0.0.1:6379> geoadd china:city 141.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 103.50 29.63 chongqing 114.05 22.52 shenzhen 116.38 39.90 beijing
(integer) 3
127.0.0.1:6379> geopos china:city shanghai
1) 1) "141.47000044584274292"
   2) "31.22999903975783553"
//获取两城市之间的距离   
127.0.0.1:6379> geodist china:city beijing shanghai km
"2455.6228"
127.0.0.1:6379> geodist china:city beijing chongqing km
"1636.7270"
//获取指定经纬度一定范围内的城市
127.0.0.1:6379> georadius china:city 110 30 1000 km
1) "chongqing"
2) "shenzhen"


10. Redis事务_锁机制


Redis事务


Redis事务是一个单独的隔离操作,事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。


Redis事务的主要作用就是串联多个命令防止别的命令插队。


mUlti,exec,discard



127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key1 value1
QUEUED
127.0.0.1:6379(TX)> set key2 value2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set a1 v1
QUEUED
127.0.0.1:6379(TX)> set a2 v2
QUEUED
127.0.0.1:6379(TX)> discard
OK


情况一:组队的时候有一个命令出错,执行时整个的所有队列都会被取消



127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set b1 v1
QUEUED
127.0.0.1:6379(TX)> set b2 v2
QUEUED
127.0.0.1:6379(TX)> set b3
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.


情况二:组队的时候没有失败,执行的时候有一个命令失败,其他的命令都会执行,不会回滚。



127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set c1 v1
QUEUED
127.0.0.1:6379(TX)> incr c1
QUEUED
127.0.0.1:6379(TX)> set c2 v2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK


事务的冲突问题


悲观锁



乐观锁


每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

抢票就是典型的乐观锁场景。




Redis事务三特性


单独的隔离操作


  • 事务中的所有命令都会序列化,按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。


没有隔离级别的概念


  • 队列中的命令没有提交之前不会实际被执行,因为事务提交前任何指令都不会被实际执行


不保证原子性


  • 事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。


12. Redis持久化之RDB


Redis提供了2个不同形式的持久化方式


  • RDB(Redis DataBase)


  • AOF(Append Of File)


RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘中,Snapshot快照,它恢复时是将快照文件直接读到内存里。


备份是如何执行的?


  • Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。


  • RDB的缺点是最后一次持久化的数据可能丢失。


读时共享,写时复制。




13. Redis持久化之AOF


AOF是什么?


  • Append Only File,以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件将写指令从前到后执行一次以完成数据的恢复工作。


  • AOF默认不开启,RDB默认开启


  • appendonly no改为yes开启


  • 如果同时开启AOF和RDB,系统默认取AOF的数据。


  • redis-check-aof --fix appendonly.aof可以修复aof文件


同步频率设置:


  • appendfsync always:始终同步,每次redis的写入都会立刻记入日志;性能较差但数据完整性比较好


  • annendfsync everysec:每秒同步,每秒写入日志一次,如果宕机,本秒的数据可能丢失。


  • appendfsync np:redis不主动进行同步,把同步时机交给操作系统


rewrite压缩


什么时候重写:


Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发


重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。


auto-aof-rewrite-percentage:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)


auto-aof-rewrite-min-size:设置重写的基准值,最小文件64MB。达到这个值开始重写


AOF持久化流程:


  1. 客户端的请求写命令会被append追加到AOF缓冲区中


  1. AOF缓冲区根据AOF持久化策略[always, everysec, no]将操作sync同步到磁盘的AOF文件中


  1. AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容器


  1. Redis服务重启时,会重新load加载AOF文件的写操作达到数据恢复的目的。


优点:


  • 备份机制更稳健,丢失数据概率更低


  • 可读的日志文本,通过操作AOF稳健,可以处理误操作


缺点:


  • 比起RDB占用更多的磁盘空间。


  • 恢复备份速度要慢。


  • 每次读写都同步的话,有一定的性能压力。


  • 存在个别Bug,造成恢复不能



哪个好?


官方推荐两个都启动。如果对数据不敏感,可以单独选RDB;不建议单独用AOF,因为可能会出现bug。如果只是做纯内存缓存,可以都不用。


14. Redis主从复制


一般是一主多从


是什么?


  • 主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主


能干什么?


  • 读写分离;容灾的快速恢复



怎么搭建一主多从?


【尚硅谷】Redis 6 入门到精通 超详细 教程_哔哩哔哩_bilibili


一主二仆


info replication可以看信息


slaveof IP 端口9可以设置从服务器


redis-server redis.conf启动服务器端


redis-cli -p 端口 启动客户端


ps -ef | grep redis:查看redis进程



主机能读能写,从机只能读



从服务器挂掉后,重启变成了主服务器


该重新设置为从服务器,能看到挂掉那段时间主服务器添加的数据


主服务器挂掉后,从服务器还是从服务器,也知道主服务器挂掉了


主服务器重新启动后,还是主服务器,数据不丢失


  1. 当从服务器连接上主服务器之后,从服务器向主服务器发送进行数据同步的消息。


  1. 主服务器接到从服务器发送过来的同步消息,把主服务器数据进行持久化,rdb文件,把rdb文件发送给从服务器,从服务器拿到rdb进行读取。


  1. 每次主服务器进行写操作之后,和从服务器进行数据同步。(主服务器主动做的)

全量复制/增量复制


薪火相传



反客为主


salveof no one将从机变为主机


非自动


哨兵模式(sentinel)


反客为主的自动版



主要是为了监控主机宕机之后,从机可以立马变为主机,就和上面的反客为主一样,但不用手动设置


能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。


15 Redis集群


容量不够,redis如何进行扩容?


并发写操作,redis如何进行分摊?




什么是集群?


  • redis集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。


  • redis集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。


创建redis集群:【尚硅谷】Redis 6 入门到精通 超详细 教程_哔哩哔哩_bilibili



16. 应用问题


1. 缓存穿透




2. 缓存击穿


key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮


也就是一个key过期,一直访问数据库



解决方案:


key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题。


(1)预先设置热门数据:在redis高峰访问之前,把一些热门数据提前存入到redis里面,加大这些热门数据key的时长


(2)实时调整:现场监控哪些数据热门,实时调整key的过期时长


(3)使用锁:先判断值是否为空再让他进来与否


总结如下:


  • 设置热门的key,加大时长过期


  • 实时监控调整


3. 缓存雪崩



解决方案:


(1)构建多级缓存架构:nginx缓存 + redis缓存 +其他缓存(ehcache等)


(2)使用锁或队列:用加锁或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。不适用高并发情况


(3)设置过期标志更新缓存:记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际key的缓存。


(4)将缓存失效时间分散开:比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。


总结如下:


  • 设置多个级别的缓存架构,时间来得及缓冲


  • 使用锁的机制


  • 设置一个过期时间标志来通知


  • 将过期时间分散,比如5分钟、5.01分钟等


4. 分布式锁


由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的Java API并不能提供分布式锁的能力。为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问


也就是在这个机器上了锁,另外一个机器也要可以识别到这个锁,也就是共享锁,都是同一把锁


解决方案如下:


  • 基于数据库实现分布式锁


  • 基于缓存(Redis等)


  • 基于Zookeeper


设置锁:setnx


释放锁:del


设置key的过期时间自动释放:exprie


zdb@zdb-virtual-machine:~$ redis-server /etc/redis.conf 
zdb@zdb-virtual-machine:~$ /usr/local/bin/redis-cli
127.0.0.1:6379> setnx users 10
(integer) 1
127.0.0.1:6379> setnx users 20
(integer) 0
127.0.0.1:6379> del users
(integer) 1
127.0.0.1:6379> setnx users 10
(integer) 1
127.0.0.1:6379> expire users 10
(integer) 1
127.0.0.1:6379> ttl users
(integer) 4
127.0.0.1:6379> ttl users
(integer) -2
//即上锁又设置过期时间
127.0.0.1:6379> set users 10 nx ex 12
OK
127.0.0.1:6379> ttl users
(integer) 3
127.0.0.1:6379> ttl users
(integer) -2


UUID防止误删



lua脚本保证原子性




17. Redis6.0新功能


1. ACL



权限控制


  • acl list命令展现用户权限列表


  • acl cat,查看添加权限指令类别


  • acl whoami命令查看当前用户


  • acl set user命令创建和编辑用户ACL


127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"
127.0.0.1:6379> acl cat
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"
127.0.0.1:6379> acl whoami
"default"


2. IO多线程


单线程+IO多路复用


redis是单线程



多线程IO默认是不开启的,需要在配置文件中设置


io-threads-do-reads yes


io-therads 4

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
缓存 NoSQL Java
springboot的缓存和redis缓存,入门级别教程
本文介绍了Spring Boot中的缓存机制,包括使用默认的JVM缓存和集成Redis缓存,以及如何配置和使用缓存来提高应用程序性能。
94 1
springboot的缓存和redis缓存,入门级别教程
|
1月前
|
存储 消息中间件 NoSQL
Redis 入门 - C#.NET Core客户端库六种选择
Redis 入门 - C#.NET Core客户端库六种选择
59 8
|
3月前
|
SQL 存储 NoSQL
Redis6入门到实战------ 一、NoSQL数据库简介
这篇文章是关于NoSQL数据库的简介,讨论了技术发展、NoSQL数据库的概念、适用场景、不适用场景,以及常见的非关系型数据库。文章还提到了Web1.0到Web2.0时代的技术演进,以及解决CPU、内存和IO压力的方法,并对比了行式存储和列式存储数据库的特点。
Redis6入门到实战------ 一、NoSQL数据库简介
|
3月前
|
NoSQL 算法 安全
Redis6入门到实战------ 四、Redis配置文件介绍
这篇文章详细介绍了Redis配置文件中的各种设置,包括单位定义、包含配置、网络配置、守护进程设置、日志记录、密码安全、客户端连接限制以及内存使用策略等。
Redis6入门到实战------ 四、Redis配置文件介绍
|
3月前
|
NoSQL Redis 数据安全/隐私保护
Redis6入门到实战------ 二、Redis安装
这篇文章详细介绍了Redis 6的安装过程,包括下载、解压、编译、安装、配置以及启动Redis服务器的步骤。还涵盖了如何设置Redis以在后台运行,如何为Redis设置密码保护,以及如何配置Redis服务以实现开机自启动。
Redis6入门到实战------ 二、Redis安装
|
3月前
|
NoSQL Java Redis
Redis6入门到实战------思维导图+章节目录
这篇文章提供了Redis 6从入门到实战的全面学习资料,包括思维导图和各章节目录,涵盖了NoSQL数据库、Redis安装配置、数据类型、事务、持久化、主从复制、集群等核心知识点。
Redis6入门到实战------思维导图+章节目录
|
3月前
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
3月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
|
3月前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
3月前
|
存储 NoSQL 算法
Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))
这是关于Redis 6入门到实战的文章,具体内容涉及Redis的五大数据类型:列表(List)、集合(Set)、哈希(Hash)、有序集合(Zset(sorted set))。文章详细介绍了这些数据类型的特点、常用命令以及它们背后的数据结构。如果您有任何关于Redis的具体问题或需要进一步的帮助,请随时告诉我。