redis是基于内存,常用作缓存的一种技术,存储方式以key-value形式,但是内部实现数据结构是hash表,每创建一个数据时,分别创建两个hash数据,保存key与value,key一定为字符串
优点:速度快,性能优越,支持多种数据结构
缺点:受物理内存限制,不能用做海量数据保存,适合利用自身内存淘汰机制保留热点数据
redis基本数据类型
1.String字符串
字符串类型可用来保存字符、整型、浮点型数据。
基本命令
- get key --获取值
- set key value (expire) --设置值(有效期)
- setnx key value --当存在该key时,返回0;不存在返回1,可用于实现分布式锁
- del key -- 删除
- incr key -- 递增
- decr key -- 递减
- strlen key -- 键长度
2. list(双向链表)
栈:先进后出 队列:先进先出
- lpush list value -- 从头部插入一条数据
- rpush list value -- 从尾部插入一条数据
- lpop list -- 从头部取出一条数据
- rpop list -- 从底部取出一条数据
- lrange list index1 index2 -- 遍历指针index1到index2到数据(0 -1时遍历所有数据)
- lrem list index value -- 删除指针为index的值为value的数据
list可用于实现简单的消息队列,两种实现方式:
- lpush与rpop
- rpush与lpop
3. set
不存在重复元素,无顺序
- sadd set value -- 往集合插入一条数据
- srem set value -- 删除set集合中值为value的数据
- smembers set -- 查询set集合中所有数据
set还能查询两个集合中的交集、差集
4. sorted set(有序集合)
与set相似,不同的是每个元素可关联一个double类型的分数,redis通过分数从小到大排序
- zadd set score value
5. hash
hash用于存储对象
redis与map的区别?
- map为本地缓存,存在缓存不一致的问题;redis实现分布式缓存,多服务共享同一缓存
- map只能存放少量的数据,jvm内存过大,容易宕机
- map存储的是临时数据,服务关闭,缓存即消失,redis可以持久化
持久化
关于redis持久化,可人工输入命令持久化,也可以系统配置。持久化命令有save,bgsave
- save会造成线程阻塞,因为redis是单线程运行,持久化时后续操作需要等待线程持久化之后继续执行
- bgsave会创建子线程完成持久化操作,存在的问题是持久化的数据可能不是最新的
持久化存储的形式有两种,分别为
- RDB快照,保存系统某一时刻的全部数据,数据为压缩后的二进制文件
- AOF,保存所执行的命令语句,客户端输入的操作命令,先缓存在aof缓存中,系统默认配置为一秒钟写入aof文件
RDB与AOF的区别?
- 恢复数据时,RDB快照速度快,文件体积小
- AOF默认一秒钟持久化一次,相对快照数据丢失率低,数据更加完整(两者同时启用时,redis默认选用AOF恢复数据)
- AOF文件体积大,恢复数据慢
过期策略
- 定时清理,到某个时间点清理过期的键
- 惰性清理,查询数据时,判断数据是否过期,过期则进行删除
- 定期清理,每隔一段时间对过期数据进行清理
redis采用了定期清理和惰性清理,所以数据过期,并不一定已经被删除
当定期清理漏掉的过期key过多并长时间未查询,导致redis垃圾数据过多,内存过大,可能影响redis的使用,需要引进内存淘汰策略
内存淘汰策略
- 淘汰设置过期时间并访问量最低的数据
- 淘汰设置过期时间并即将过期的数据
- 淘汰设置过期时间中任意数据
- 淘汰访问量最低的数据
- 从所有数据中任意淘汰
- 禁止淘汰数据
主从复制
单实例的redis可能存在以下问题:
- redis挂掉后,系统无法使用
- redis能承受的访问并发量也是有限的
- 当大量的访问请求过来时,如果redis无法正常使用,请求将直接到数据库,数据库可能会因此宕机
为了解决以上问题,引入redis的主从复制,读写分离
从节点redis.conf配置以下内容

启动后,主节点状态信息如下:

offset表示复制偏移量,表示的是主节点发送的数据量,从节点接收的数据量
lag表示几秒前有心跳检测
从节点状态信息如下:

主从复制原理:
- 设置主服务器IP以及端口,命令为slaveof IP PORT
- 与主服务器进行socket连接
- 发送ping命令,检验socket状态是否正常,不正常则断开连接重试
- 身份校验
- 从服务器发送自身IP、端口到主节点记录
- 向主节点发送PSYNC命令,执行同步操作,这时主节点有两个操作,第一个是执行bgsave命令,创建子线程生成RDB文件并发送到子节点;第二个是将后续操作命令存放于缓存中并发送到子节点。子节点收到RDB文件恢复数据,此时子节点的数据与主节点生成RDB之前的数据一致
- 进入命令传播模式,主节点有写命令操作时,将命令发送给子节点
命令传播模式,如何保证主节点与子节点一直处于连接状态呢?
- 子节点利用心跳机制定时发送命令给主节点,命令为REPLCONF ACK <replication_offset>,replication_offset表示当前从节点复制偏移量
心跳机制有以下几种作用?
- 检查主节点与从节点的网络连接状态
- 检查是否有命令丢失,如有主节点将补发命令
同步原理
同步命令:PSYNC runid offset
- 全量重同步
- 部分重同步
- offset复制偏移量
- runid运行ID,redis运行时生成的ID,初次复制时主节点将发送给子节点,同步时,当runid不同时将全量重同步,否则部分重同步
- 复制缓冲区,为一个队列,先进先出。当进行全量重同步时,一方面生成RDB文件,一方面将写操作将保存到复制缓冲区。同步时当从节点与主节点的offset之差大于缓冲区大小时,将执行全量重同步
主从复制还存在一些问题,当主节点挂掉时,将影响到整个系统。