Redis总结
2020-01-03 09:50:12 0 举报
AI智能生成
登录查看完整内容
Redis知识总结图
作者其他创作
大纲/内容
Redis总结
原理篇
Redis运行机制
纯内存结构
KV结构,时间复杂度O(1)
虚拟存储器(虚拟内存映)
用户空间和内核空间
进程切换
文件描述符FD
传统I/O数据拷贝
阻塞I/O
I/O多路复用
以上内容,建议了解下得了。。。理解起来真的有点困难
单线程
好处
没有创建线程、销毁线程带来的消耗
避免上下文切换导致CPU消耗
避免线程之间的竞争,例如锁
为什么是单线程
官方解释说:单线程够用了。。。TMD
多路复用
这边建议了解下得了
说话,没听懂
内存回收
过期策略
定时过期
每个key设置一个定时器,到时见立即清除
优点:对内存友好
缺点:占用大量CPU资源处理过期数据,影响响应时间和吞吐量
惰性过期
只有访问一个key的时候,才判断key是否过期
优点:节省CPU资源
缺点:对内存不友好,大量过期key未被访问的情况下,一直占用着内存
定期过期
折中方案,定期批量检查key,清除其中过期的key
redis采用了惰性和定期两种过期策略
淘汰策略
最大内存设置
redis设置了最大内存,到极限时会触发
LRU和LFU
了解得了,算法。。呵呵
持久化
RDB
redis默认持久化方案
当满足一定条件,会把当前内存数据写入磁盘,生成快照文件dump.rdb
重启通过dump.rdb文件恢复数据
触发方式
shutdown触发,保证服务器正常关闭
flushall,RDB文件是空的
手动触发
优势
rdb是一个非常紧凑的文件,保存了redis在某个时间点上的数据集,非常适合用于备份和灾难恢复
生成rdb文件时,redis主进程会fork一个紫禁城来处理保存工作,主进程不需要进行任何磁盘IO操作。so 异步的??
RDB恢复大数据集速度比AOF快
劣势
rdb方式没办法做到实时持久化,秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,频繁执行成本过高
一定时间间隔做一次备份,依赖down的话,就会丢失最后一次快照之后的修改,数据有丢失
数据比较重要,损失降到最小,用AOF方式
AOF
默认不开启
采用日志形式记录每个操作,并追加到文件,开启后,执行更改命令,就会写入AOF文件
重启时,把日志文件的内容从前到后全部执行一次来恢复
数据并没有进入磁盘,而是磁盘缓存
文件越来越大
两种方案比较与选择
显而易见,各取所需
官方提供的测试QPS命令
实战篇
实战就没必要那么详细了
客户端
Jedis
最常用了吧
4中工作模式
单点、分片、哨兵、集群
3中请求模式
client、pipeline、事务
连接支持
sentinel
cluster
分布式锁
Luttece
了解
redisson
自带分布式锁api
客户端通信原理
可抓包观察下
客户端和Redis之间使用的是一种特殊的编码格式,Redis Serialization Protocol协议
数据一致性问题
先更新库,还是redis
高并发问题
热点数据发现
这个也要多种解决方案,但是感觉不是高并发中的重点
缓存雪崩
经典问题
Redis中的key在同一时间点同时过期,所有的请求都落到了数据库,并发量大的情况下,啧啧。。。
解决方案
加互斥锁或者队列,同一个key只允许一个线程到库里查询
缓存定时预更新,避免同时失效过期
通过给key设置随机数过期时间
永不过期。。牛逼
缓存穿透
Redis和库中都不存在的值,每次请求都会走一遍库里和Redis
缓存空字符串
缓存特殊字符串
注意设置过期时间,不然库里真有那条数据后,还是获取不到
经典面试题
如何在海量元素中(例如 10 亿无序、不定长、不重复)快速判断一个元素是否存在?
位图
位图映射
哈希碰撞
布隆过滤器
成功率
Guava中有实现
使用应该不复杂,但是原理理解起来好难
基础篇
诞生
作者:antirez
Redis全称:Remote Dictionary Service
定位与特性
NoSQL
Not Only SQL
non-relational
定位
非关系型数据库
存储结构以KV形式,没有表概念
没有表关联,扩展性强
保证数据的最终一致性,遵循BASE(碱)理论
Basically Available(基本可用)
Soft-state(软状态)
Eventually Consistent(最终一致性)
支持海量数据存储和高并发的搞笑读写
官方QPS10W+?
支持分布式,可分片存储,扩缩容简单
特性
丰富的数据类型
单机、分布式
持久化、过期策略
支持多种语言,针对的客户端吗?
高可用、集群
安装启动
略
基本数据类型
String
存储类型:字符串、整数、浮点数
操作命令
set、get、mset、mget、setnx...
存储(实现)原理
略,了解下得了
底层是通过C语言通过hashtable(外层哈希)实现的
感觉像单向链表
底层又封装了dictEntry,存储了key和value的指针
key存储在自定义的SDS,value存储在redisObject
编码类型有int、embstr、raw的区分
应用场景
热点数据缓存
分布式数据共享,如session共享
分布式锁,基于setnx
生成全局ID,基于INCRBY
计数器,INCR
限流,如访问IP次数限制
位统计,非常节省空间,像后边讲的布隆过滤器
Hash
key、field、value
包含键值对的无需散列表。value只能是字符串,不能嵌套其他类型
与String类型的区别
把相关值聚集到一个key,节省内存空间
只使用一个key,减少key冲突。PS:这点感觉有点牵强,field多了啊
批量获取数据方便,一个命令,并且减少了IO/CPU消耗
不适合场景
field不能单独设置ttl
没有bit操作
要考虑数据分布问题,value值非常大的时候,没有办法分布到多个节点
hset、hget、hmset、hmget...
ziplist、hashtable
String能做的,hash都可以
List
存储类型
有序字符串(从左到右),元素可重复。可作为队列和栈的角色。
lpush、rpush、lpop、rpop、blpop、brpop、lindex、lrange...
存储原理
ziplist、linkedlist、3.2版本之后统一用quicklist,双向链表。。。
用户消息时间线,因为是有序的
消息队列
Set
String类型的无需集合,最大存储数量2^32-1(40亿左右),卧槽。。。
sadd、smembers、scard、srandmember、spop、srem、sismember...
intset、hashtable
如果元素都是整数类型,就用inset,如果不是就用hashtable(数组+链表)
元素个数超过512个,也会用hashtable。redis配置文件可设置
随机获取元素可用于抽奖
点赞、签到、打卡
比关系型数据库简单
商品打标签
商品筛选
差集、交集、并集
sdiff、sinter、sunion
用户关注
相互关注、可能认识的人...
ZSet
Sorted set
有序set,每个元素有个score
score相同,按照key的ascii码排序
元素不允许重复
zadd、zrange、zrevrange、zrangebyscore、zrem、zscard...
ziplist、skiplist
排行榜
其他数据结构
BitMaps
位操作
Hyperloglogs
统计??
Streams
。。。
高级特性
发布订阅
list
存在局限性
不停的轮询lpop查看list中是否有等待消费的消息,比如while
减少通信消耗,可以sleep一段时间再去消费
但是生产者生效速度大于消费速度,消息会积压,占用大量内存
消息实时性降低
不支持一对多
发布订阅相关命令
subscribe channel...
publish channel
unsbscribe channel
还要一些可以用通配符形式发布/接收消息的机制
以上我觉得了解下得了....
事务
特点
按进入队列顺序执行
不会受到其他客户端请求影响
命令
multi(开启事务)、exec(执行事务)、discard(取消事务)、watch(监视)
为什么Redis事务不支持回滚
官网的解释很有意思
我理解的大概意思就是,redis觉得这应该程序员编程上犯的错误,应该在开发阶段就发现并纠正,不能上生产环境....
Lua脚本
了解下得了
但是后边有些开源的三方客户端,如redisson,貌似源码中好多地方用到lua脚本
分布式篇
为什么需要集群
性能
扩展
这块儿没太明白
加实例?加硬件?横向扩展?
可用性
没有什么服务比7*24小时的HA更实实在在的了
主从复制
配置
redis.conf增加slaveof ip port
启动服务时指定master节点:./redis-server --slaveof ip port
查看集群状态:info replication
这边有个有意思的故事,说是master/slave的说法有奴隶之嫌,作者就发起了投票改成了master/replicaof...人权啊
从节点只读,只能从master节点同步数据
原理
连接阶段
slave启动时,保存了master node的信息,host和ip
slave node内部有个定时任务,每隔1秒检查是否有新的master node需要连接和复制,如果有,就简历socket连接,并建立一个专门的事件处理器,负责复制工作,如接受RDB文件和命令等
数据同步阶段
第一次全量复制,通过RDB快照发给slave,slave首先清除自己的旧数据,然后rdb文件加载新的
master新命令缓存到内存,slave保存rdb之后,再复制给slave
命令传播阶段
master node持久将写命令异步复制给slave node
有延迟
断了一段时间,重新连接
有偏移量增量复制
不足
虽然解决了备份和性能(读写分离)问题
RDB文件过大,同步耗时
一主一从或者一主多从,主挂了,服务就不可用了
还得手动把从切换成主,而且耽误时间
自动切换?
通过运行监控服务来保证可用性
特殊状态的Redis实例
除了监控所有的Redis服务,sentinel之间也互相监控
服务下线
主观下线
sentinel每秒钟1次的频率向Redis节点发送ping,没收到回复,就标记为下线
客观下线
然后再去问其他的sentinel,大多数反馈下线状态,master就会确认为下线
需要重新选举
故障转移(failover)
选举
选一个sentinel的leader做故障转移
Raft算法
了解下得了。。。
算法演示地址:http://thesecretlivesofdata.com/raft/
步骤
选出sentinel leader,向某个节点发送slaveof no one命令,成为独立节点(自己是自己的master)
然后向其他节点发送slaveof host port(本机服务),让它们臣服自己的节点
选谁成为主节点?
四个因素影响选举结果
断开连接时长
优先级排序
复制数量
进行id
实战
略。。。
建议找篇文档实操一遍,做做笔记,写写blog
哨兵机制的不足
主从切换过程中会丢数据,因为只有一个master
只能单点写,没有解决水平扩容
数据量大了的话,分片呢??数据如何分布??
分布式方案
客户端实现分片逻辑
如Jedis提供了Redis sharding方案,还有连接池
优点
不依赖其他中间件
分区逻辑可以自定义,灵活
缺点
不能实现动态服务增减,扩缩容??
自己维护分片策略逻辑,就是自己写代码呗,还有可能分的不均匀么
代理Proxy
Twitter的Twemproxy
豌豆荚的Codis
就是client和Redis server中间加个proxy层呗,上边两个都是开源的,自行百度了解下得了
Redis Cluster
既能解决分布式,又可以实现高可用
所以用这个方案就可以替代sentinel了??
架构和数据分布
这里边引入了一个好复杂的概念,一致性哈希,哈希环。。。听不懂
还有这种形式增加删除节点的时候,数据依然可以最大化的均匀分布,不受影响。。。牛逼,听不懂
高可用和主从切换原理
感觉就是发现master变为fail了,slave就积极的发起投票,选举新master,成为master之后广播一下通知其他集群节点
集成了主从复制和哨兵高可用的功能
总结
无中心架构
动态调整数据节点上的分布
可扩展
高可用
运维成本降低,自动的呗
其实个人感觉就是数据节点扩展方案,而且分布均匀,并且高可用
缺点很多,但我不是很理解
client实现复杂,开发难度大
节点会因为某些原因阻塞,阻塞了会故障转移,就是主从切换呗,没有必要
数据异步复制的,数据强一致性不能保证
没办法区分冷热数据,资源隔离性差,互相影响
遗留问题
所以面试常说的Redis有几种部署模式是??
单点、哨兵和Redis Cluster?
还有目前我们项目中的两种redis配置就是对应的哨兵和Redis Cluster?
我也没觉得client实现复杂啊?
0 条评论
回复 删除
下一页