redis总结

常用命令

set

sadd scard sdiff sinter sismember smembers smove spop sscan sunion srem srandmember

sorted sets

zadd zcard zount zincrby zrange zrank zrem zscore zscan

strings

append bitcount bitfield bitop bitops decr decrby get getbit getrange getset incr incby mget
mset set setex setnx setrange strlen setbit

哈希

hset hmset hsetnx hscan

hyperLogLog

原理
每个要统计的key可以哈希到64位的数字上,根据概率计算,连续1或者连续0的概率会指数下降,数据够多的情况下连续的个数也会越多,只需要一个6位的桶就能统计到当前最大长度(因为不会超过64),但是只用一个桶统计误差太大,所以分散存储到16384个桶(14位),取算调和平均值,这样会趋近于大多数桶统计的数量。
使用12k的空间存储唯一元素,可以统计大量的数据,误差百分之0.81。分为16384个桶,每个桶6位。
PFADD PFCOUNT PFMERGE

keys

exists expire keys(线上不要使用) ttl scan(线上不要使用)

lists

blpol(阻塞获取) brpop llen lindex lpop lpush lpushx lrange lrem lset rpush ltrim

pub/sub

psubscribe publish pubsub punsubscribe subscribe unsubscribe

streams

xack xadd xclain xdel xgroup xinfo xlen xpending xrange xread xreadgroup xtrim

scripting

eval evalsha (script debug) (script exists) (script flush) (script kill) (script load)

server

bgsave (config get) (config set) (info) (monitor) (slowlog) (slvaeof) replicateof role

transcations

multi exec watch unwatch discard

pipline

多条命令一起发送,网络交互次数少提高性能。

pub/sub

eval(lua scripting)和调试

redis事务(multi exec discard watch)

分布式锁(redlock)

配置一个节点取代setnx key expire

Redis Keyspace Notifications

二级索引

streams

采用radix tree基数树来存储。
注意:
1.每个streams需要一个连接
2.集群上使用,支持扩容,但是每个streams只能在一个分片上。

modules模块开发

性能分析,延迟分析,内存优化

慢查询

配置文件配置或者config set相关参数。
slowlog get

monitor

调试可以使用,监控当前发生的所有操作记录

高可用集群(cluster和sentinel)

复制功能

psync取代sync

sentinel哨兵模式

只需要三个哨兵就可以管理任意数量的副本。

cluster模式

ask只转向一次,moved永久迁移。
选举不管是哨兵还是集群模式都使用raft算法。

分片机制

按key分片,例如同一个streams,同一个哈希key会落在一台机器上,可以使用hscan扫描。同时带来了热key和大key的分布不均匀问题。
解决思路:客户端统计然后拆分;代理服务或发送到其他服务统计然后拆分;使用monitor监控,线上不推荐,影响业务。
注意:
分片会导致跨多节点指令执行失败,事务基本不能用,lua脚本也不行,扫描key不行。

一致性哈希

直接通过哈希然后根据范围指定落在那个分片上,节点宕机或者扩容都会导致大量key需要迁移。可以通过增加比较多的虚拟节点,这些虚拟节点挂到真实节点上,扩容缩容都只影响到一个节点的数据量。

配置和优化

linux内核参数优化

/proc/sys/vm/overcommit_memory vm.overcommit_memory=1 //0内存不够会失败,1允许超量使用内存直到用完,2觉不过量,且默认百分50。建议设置为1。

/proc/sys/vm/swappiness swappiness 使用swap的意愿0-100,默认60,可以考虑关闭oomkiller,有可能把redis进程杀掉,或者将redis服务进程的oom_adj设置低一些。

/sys/kernel/mm/transparent_hugepage/enabled THP 内存大页,支持大于2mb内存页分配,默认开启。建议禁用,大页内存写磁盘更加消耗cpu。

内存太大情况下的备份

不管是rdb还是aof都需要fork进程,让子进程进行备份操作。单机内存超过10g就要慎重考虑备份了,直接使用副本集,然后备份备机的数据。

多级副本

减少主节点复制开销。

其他技巧

布隆过滤器

使用bitmap实现或者使用redis插件。
原理:
一块空间按位存key的哈希值,如果一个哈希对应的1的位数不能在这块空间找到那肯定没有存过,只会有将没有存过误判为存过的概率。要想绝对准确,使用string的位图setbit bitop等操作。要降低误判率,可以增加哈希的位数,或者增加多个哈希算法,匹配多个。

过期键删除策略

定时删除,惰性删除(获取该键时删除),定期删除
内存溢出控制策略:noeviction拒绝写入,volatile-lru删除超时数据,allkeys-lru删除任何数据直到内存足够,allkeys-random随机删除任何数据,volatile-random随机删除过期数据,olatile-ttl删除快要过期的数据。

线程模型

处理命令逻辑的主线程,包含连接的建立和消息收发。
bio_close_file关闭文件的线程
bio_aof_fsync刷盘的线程
bio_lazy_free处理删除释放操作的线程
jemalloc_bg_thd内存池分配的线程,jemalloc库需要。

缓存淘汰策略

lru 最近最少使用
lfu 最少使用,和lru区别是,lru只关心最近的,lfu统计很长一段时间的使用频率,但可能刚被使用。
fifo 先进先出

缓存穿透,雪崩解决

缓存穿透:缓存空对象,布隆过滤器
雪崩:使用集群或者哨兵保证高可用,隔离组件限流降级,提前演练。

警惕的命令

keys flushall/flushdb save debug config shutdown
解决方案:
rename-command

bigkey问题

1.执行debug object key查看serializedlength属性即可判断一个key是否为
bigkey
2.线上环境可以通过其他手段,比如客户端收集,慢查询日志,或者scan debug object渐进式扫描(慎重,可以搭配pipline,有副本,使用副本查询)。sscan,hscan,zscan。Redis在4.0版本支持lazy delete free的模式,删除bigkey不会阻塞Redis。

热key问题

上面已讨论过

info中的统计信息

技巧

1.string的incr用于乐观锁 incr:递增数字,可用于实现乐观锁 watch(事务)

原理与源码分析

resp协议

redis客户端和服务端通信使用的协议,key可以是二进制,但一般都使用字符串。

数据结构

sds:包含使用长度,分配的大小,1个标志字段,空数组占位(指向分配的内存,不占用结构体空间),sds的append操作会重新malloc内存,不自觉维护内存池,因为使用的tcmalloc或者jemalloc已经维护了内存池,性能还不错。

adlist:struct list包含struct listnode,节点复制节点释放节点匹配的函数指针。

dict:所有的key查找都需要通过字典,无论要找的是什么类型,key就是个sds。每个客户端请求的连接里会指向一个dict,dict中有两个hashtable,为了实现rehash。当然每个hashtable中有冲突也可以用链表链接。使用渐进式rehash慢慢迁移老的hashtable数据到新hashtable,rehashidx记录这一迁移进度。

skiplist:跳表是用来取代需要平衡二叉树和红黑树的场景。比如zset有序集合,查找就用到跳表,时间复杂度近似于O(logN)。层级越高数据结构大小越大,每个节点都至少有一层的数据要保存,平均到每个节点就不是很大,这里也使用了未指定大小数组的技巧。

intset:整数集合底层实现是数组,有序不重复保存,插入元素会导致内存拷贝。插入和删除复杂度是O(N)

ziplist:压缩列表,适合少量数据存储。

quicklist:取代ziplist和linkedlist,或者说是两者的结合,每一段用linkedlist连接,一段内使用ziplist或者不编码。

listpack:紧凑列表

redisObject:所有对象的内部结构定义。

radix tree:基数树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值