redis相关原理 有更新!

  ,
评论 • 100 浏览

mmexport1553615068342jpg

redis池化管理

客户端连接Redis使用的是TCP协议,直连的方式每次需要建立TCP连接,而连接池的方式是可以预先初始化好连接,所以每次只需要从连接池借用即可,而借用和归还操作是在本地进行的,只有少量的并发同步开销,远远小于新建TCP连接的开销。另外直连的方式无法限制连接对象的个数,在极端情况下可能会造成连接泄露,而连接池的形式可以有效的保护和控制资源的使用。

spring目前支持两种类型的连接池,jedisPoollettucePool。Lettuce是一个基于netty的开源连接器,由SpringDataRedis通过org.springframework.data.redis.connection.lettuce包支持。lettuce使用netty性能卓越,并且支持redis主从监听。

redis池化设计和jdbc连接池等池化设计理念是一致的。都是为了减少连接开销,增加复用,提高性能。

redis持久化

redis持久化分为两种:

  • RDB
  • AOF

RDB是redis默认持久化的方式。也是官方建议的一种方式,官网描述后续可能会将RDB和AOF进行统一。Note: for all these reasons we'll likely end up unifying AOF and RDB into a single persistence model in the future (long term plan).摘自官网

在客户端:可以通过执行save和bgsave命令来执行RDB操作。所不同的是save命令使用主进程执行RDB操作,bgsave会fork一个子进程进行RDB备份。由于redis是单线程的,因此save操作执行的时候redis会阻塞,无法响应其他操作。

在配置文件:配置文件默认是RDB,可以通过配置save 秒 次数来指定RDB保存快照策略。例如save 10 5,如果redis在10秒达到5次修改操作的阈值将会触发一次快照存储。
注意:这里的秒是指redis定时执行检查的周期,比如你在一秒内有100次命令操作,redis也是会在10秒后进行一次快照。如果10内没有达到阈值,那么redis不会进行一次快照存储。但是redis会进行记录,等到达到操作的阈值时,便会进行一次快照存储。

RDB优势:对性能影响最小,数据恢复速度比AOF要快。
RDB劣势:在执行周期内如果发生服务意外,有可能会丢失数据。

AOF 持久化更加健壮。在配置文件中配置appendonly yes来开启aof持久化。aof比rdb有更好的持久化性,是由于在使用aof持久化方式时,redis会将每一个收到的写命令都通过write函数追加到文件中(默认是appendonly.aof)。

aof持久化策略:

  • appendfsync always
    每次收到写命令就立即强制写入到磁盘,最慢,但是保证完全的持久化,不推荐用。

  • appendfsync everysec
    每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐使用。

  • appendfsync no
    完全依赖OS,性能最好,持久化没保证。

理论上,如果采用appendfsync everysec 这种方式进行持久化,也是有可能会丢失一秒的数据的。

APF优势:安全,容灾,易读,可直接修改aof文件。
AOF劣势:文件体积大,性能消耗比RDB高,数据恢复比RDB慢。

redis超时删除策略

redis的key过期删除策略分为两种。

  • 被动删除。
  • 主动删除。

被动删除: 当一个key被访问时,并且redis发现该key已经过期,那么就会删除该key。
当然,这是不够的,因为有的key可能永远不会被访问到,那么依靠被动删除是没有办法将这些key删除干净。所以redis中也会定期进行主动删除。
主动删除: 具体来说,Redis每秒10次执行以下操作:
1. 从具有相关过期的密钥集中测试20个样本随机密钥。
2. 删除找到的所有密钥已过期。
3. 如果超过25%的密钥已过期,请从步骤1重新开始。

数据恢复阶段过期数据处理策略

RDB: 过期的数据不会持久化到文件中。载入时过期的数据会通过上面的redis主动和被动的方式删除。
AOF: 当redis使用AOF方式持久化的时候,每次遇到过期的key,redis就会追加一条DEL命令到AOF中。只要顺序加载AOF命令,就会删除过期的键。

注意: 上述两种方式和服务器时间相关

redis内存管理

数据类型大小限制:

  • String类型:
    一个String类型的value最大可以存储512M。

  • Lists类型:
    list元素个数最大为$2^{32}-1$个,也就是42949672295个。

  • Sets类型:
    元素个数最多为$2^{32}-1$个,也就是42949672295个。

  • Hashes类型:
    键值对个数最多为$2^{32}-1$个,也就是42949672295个。

内存优化

内存压缩

在redis中可以通过开启内存压缩来达到以更小的内存代价存储更多的数据。

  • hash-max-zipmap-entries 512 (hash-max-ziplist-entries for Redis >=
    2.6)
    当hash元素个数<=512个,进行hash压缩。

  • hash-max-zipmap-value 64 (hash-max-ziplist-value for Redis >= 2.6)
    当hash值<=64个字节时,进行hash压缩。

  • list-max-ziplist-entries 512
    list元素个数<=512个,进行压缩。

  • list-max-ziplist-value 64
    list元素值<=64个字节时,进行压缩。

  • zset-max-ziplist-entries 128
    当zset元素个数<=512个,压缩

  • zset-max-ziplist-value 64
    当zset值<=64个字节,压缩。

  • set-max-intset-entries 512
    set元素个数<=512,压缩。

内存回收策略

回收策略是指redis内存不足,继续进行内存相关操作的策略。

  • 配置
    配置文件中设置:maxmemory-policy noeviction
    客户端调整:config set maxmemory-policy noeviction

  • 策略

回收策略 说明
noeviction客户端尝试执行内存使用命令时直接报错
allkeys-lru在所有key里执行LRU算法
volatile-lru在所有已经过期的key里执行LRU算法
allkeys-lfu在所有key里面使用LFU算法
volatile-lfu在已经过期的key里面使用LFU
allkeys-random所有key里面随机回收
volatile-random已经过期的key里面随机回收
volatile-ttl回收已经过期的key,并且优先回收ttl(存活)较短的key

注意:LFU在redis里面是一个近似实现,会使用基于概率的对数计数器来记录访问次数,同时计数器会随着时间推移减小。
启用LFU算法之后,可以开启热点数据分析功能。redis-cli - - hotkeys

评论
validate