1.Redis的应用场景
Redis支持类型:String、hash、set、zset、list
String类型
hash类型
set类型
zset类型
list类型
一般用作缓存,例如 如何同时操作同一功能
2.redis是单线程
Redis服务端(数据操作)是单线程,所以Redis是并发安全的,因为无论客户端有多少个请求线程,在Redis执行命令时还是顺序执行
但是I/O线程(网络请求)在Redis6.0版本之前是和服务端共用一个线程,Redis6.0版本之后就和Redis服务端不共用。
所以如果删除key或者新增key时,若数据量很大会造成阻塞,因为命令排队执行
3. redis底层结构
Redis由key-value形式存储在哈希字典dict中。
key通过hash算法转换为数字根据下标存储在数组中,但是也会存在不同的key通过hash算法计算出相同下标,此时会对相同下标进行链表存储,若数组长度大于64且链表大于8,则会转换为红黑树存储;当红黑树长度为6时则会自动转换为链表式存储。【hashmap的底层】
dict由两个数组(ht[0]/ht[1])、重新哈希索引构成。而数组ht[0]则是由dictEntry链表、数组大小、数组已用大小构成。dictEntry由key、value、next(下一个指针)组成。
扩容rehash
- 每个数据库中都有一个dict存储key-value数据,维护了两张hash表。正常使用0号表,若需要扩容,rehash时需要0号表和1号表共同使用。
- 查询时先从0号表中找,后判断是否在rehash,若在rehash则从1号表找;若不在则直接返回
- 插入时若发生rehash时插入到1号表,若未发生rehash时则插入到0号表。
key是字符串类型,value可以是String、list、set、zset、hash。
字符串String
type:String
encoding:raw/embstr、int 对应的内部结构是sds、int
sds:简单动态字符串,和Java的StringBuffer类似,可自动分配内存及释放内存
其他类型TODO
4.set命令使用时一般会对key设置过期时间
set命令若是没有对key设置过期时间,一般默认永不过期;所以一般redis用作缓存时读取到数据后会将数据清除,或者对数据设置过期时间
5. redis过期策略
当redis所用内存超过maxmemory时,会触发主动清理策略,所以若未出现误操作,redis没有过期但是数据还是被删除了,原因可能是这个主动清理策略导致的,可以看是否是这个原因;
此时默认为0,表示没有设置最大内存
- 针对设置过期时间的key:
- volatile-ttl:根据过期时间的先后顺序进行删除,越早过期越先被删除;
- volatile-random:随机删除
- volatile-lru(least recently used):最近最少使用
- volatile-lfu(least frequently used):最近不经常使用
- 针对所有key:
- allkeys-random:随机删除
- allkeys-lru:最近最少使用
- allkeys-lfu:最近不经常用
- 不处理:
- noeviction:不会删除数据,只是再次访问提示报错
一般都使用lru算法;但热点数据会使用lfu算法;
过期可以删除策略
惰性删除
key过期时是不会检查的,只有再次访问到key时(get命令)才会检测是否已过期,过期则会删除,但是不是会访问全部key的;所以存在大量过期key未被删除,占用内存;
定期删除
每隔一段时间检测key是否过期,过期则删除;可通过配置时间间隔(set命令的过期时间)来调整,视项目情况而定
定时删除
通过集合及定时器来删除(zadd命令),对每个过期时间的key建一个定时器,到过期时间则删除key,所以耗CPU,影响服务的响应时间;
Redis将惰性删除和定期删除的结合使用
6.redis主从、哨兵、集群
主从
主节点(master)提供对外服务,从节点(slave)主要是备份;当master挂了,运维人员会介入将其他slave中的一台作为master,待之前挂掉的master恢复后,以slave模式启动,以当前master为主节点(ABC三个节点,开始A为master,BC为slave节点,当A挂掉时,将C作为主节点,AB为从节点继续工作)
哨兵
- 哨兵集群会随时监控master节点与slave节点的状态及情况,当master节点挂掉时,会自动判断哪台slave节点作为master节点并将其他节点改为以master节点为首的slave节点,所以哨兵模式不需要运维介入,自己执行,但是时间就说不准,可能几秒或十几秒的。
- 当有客户端请求访问,优先发给哨兵判断哪台为master节点,得到结果后,再去访问master节点。
- 因为哨兵模式是自己执行,所以时间不确定,若此时有请求进来,会造成瞬间访问断联的情况。
- 每个节点的内存不宜过大,因为持久化文件过大,导致主从数据同步非常慢。
集群
- 集群主要解决高并发操作;
- 集群由多个分片构成的,每个master存储不同的数据,各master之间是互通的,可以检测心跳
- 当出现某一个分片的master挂掉,该分片下面的某一个slave会调整为master节点,其他节点会调整为slave节点。
redis集群数据hash分片
redis集群将数据分为16384个槽位,每个节点占用一部分槽位,槽位信息存储在每个节点;
客户端发送请求后,会先根据key计算出hash值,后除以16384取余得到所在节点的位置;
redis集群的节点超时限制
若由于网络信号问题,出现检测不到其中master节点信息,此时会自动判断并选举新的master节点。若出现网络频繁抖动,则会频繁主从切换。此时可配置节点超时信息配置
redis.conf配置文件 cluster-node-timeout 15000
redis集群的master节点要大于3个
当集群中一个分片的master挂掉后,该下面的slave节点选举是由其他分片的master节点参与的,要大于集群的一半的master节点同意才可选举成功。