前言:
渐进式hash:阻塞问题,通过进来一个迁移一部分,慢慢迁移,类似于concurrenthashmap,创建一张新的表,一个负责并发查询,插入等,另一个负责迁移,没必要用更复杂的数据结构(红黑树)去干一件没有什么性能提升的事情。
三高:
- 高性能:
- 单线程:无线程上下文切换,cpu并不是redis的瓶颈,处理一条指令不超过10us,网络和io才是
- 数据结构:全局Hash,不同数据结构不同复杂度
- epoll:多路复用
- AOF:
- 高可靠:
- AOF
- RDB
- 哨兵
- 集群
- 高拓展:
- 负载均衡 分槽
- 数据分片(虚拟槽分区)
禁止keys *,查看数量使用dbsize,内置计数器
数据结构:
String:
- 应用:
- 缓存:加快读写同时降低后端存储器Mysql的压力
- 共享session:联系springSession解决session只存在一个服务器的情况,就从redis中查询缓存信息。
- 底层数据结构:动态字符串
- 常见命令:
- set、get、del、incr、decr
- 其他几种数据结构都是在字符串类型基础上构建的(提供了位操作的指令),所以字符串类型能为其他四种数据结构的学习奠定基础,不超过512M
Hash:
- 映射关系为field:value,即一个key下面有一个entry,field不可重复
- 底层数据结构:hash表和压缩列表
- 常见命令:
- hset key field value
- hget key field
- hdel key field
- 应用:
- 存储对象信息,可以对比String存储(存储分散,key太多),序列化存储(存在一定开销),合理使用可以减少空间消耗。
List:
- 有序可重复,最大个数2^32-1
- 底层数据结构:快速列表,结合了压缩列表和双向链表的优势
- 常见命令:
- lpush key value
- rpush keyvalue
- lpop,rpop
- 应用:简单的消息队列(可阻塞)、栈,有序性可做成文章列表
Set:
- 不可重复
- 应用:打标签,取交集,取并集,随机抽奖
- 常见命令:
- sadd key member
- sdiff key1 key2
- sunion key1 key2
- 底层数据结构:整数数组和hash表
ZSet:
- 有序不可重复
- 应用:排行榜、播放量、点赞、关单操作配合延迟队列或者定时任务
- 常见命令:
- zadd key score member
- zrange key start end
- zrevrange key start end(倒序)
- 底层数据结构:压缩列表和跳表
Bitmaps:
- Redis中的Bitmap操作是基于字符串类型实现的,这些字符串值在底层由SDS表示,但Bitmap的操作是针对字符串的二进制位进行的。Redis提供了一组专门的命令来操作字符串值中的位
- 优势:以位操作,更小的存储空间实现更大的存储
- 常见命令
- setbit key offset value
- getbit key offset
- 应用:布隆过滤器(初始化的时候需要去算预估数量和hash函数个数),Hash算法+BitMap,存在可能没有,不存在一定没有
- 黑名单,缓存穿透
- 缺点:假阳性率,事先需要预估,无法移除元素,hash函数数量和数组大小难以判定
HyperLogLog:
- 记录每个网页每天的UV数据(独立访客,去重),如果用集合Long去处理,存储量很大,不精准的去重统计。0.81%
- 常见命令:pfadd、pfmerge(合并多个)、pfcount
- 原理:伯努利实验,最大似然估计,调和平均数,将元素转成64位比特串
- 伯努利:抛硬币,相当于出现这种情况的概率的导数代表抛了几次,即在其中看作,这里面已经出现了多少种情况,但是非常不准确,误差很大,分桶优化(每个桶只用存6个位的二进制),表示第几个位出现了,
- 调和平均数:降低极端情况的影响
- 低14位分桶,高50位看最低位的1,如果大于原本桶就替换,没有就不管
Geo:
- 地理位置
- 通过Redis的GEOADD key 经纬度 名称 将用户的经纬度存在一个指定的键值中,然后通过redis的GEORADIUS命令查询指定经纬度附近一定范围的用户,商家什么之类的
高级特性:
慢查询:记录在slowlog的日志中(内存队列)队列大小128也可以修改,有大小限制,就可以定时任务定期将慢查询持久化
- 针对执行命令这里,不能针对整个执行的事件
- 阈值:10ms,单位是微秒,
- 及时生效,小于0代表都不会记录
- 慢查询建议 1000以上,线上一般是1微妙,高并发高性能可以修改为1000,100,看线上执行情况
pipeline:
- 大部分时间花费在发送命令和返回结果之上,将所有命令进行组装,通过pipeLine做批量处理
- pipeLine的时候,