Redis特性解读


我的个人主页:蚂蚁的宝藏

传统数据库遵循ACID原则,而NOSQL遵循CAP原则。

Consistency(一致性): 所有节点在同一时间具有相同的数据
Availability(可用性):集群中一部分节点失效后,集群整体保证响应客服端的读写请求
Partition tolerance(分区容灾性):系统中任意信息的丢失或失败不会影响系统继续运行。

任何时候,最多满足以上两点,在分布式存储中,分区容灾性是必须的,所以在一致性和可用性上要做出权衡。redis在一致性上做出了妥协,采用结果最终一致性的弱化处理数据异步复制。

redis演变

复制

redis提供复制功能,用户可以通过复制master来创建多个slave。只要主从服务器之间通信正常,会保持相同的数据,master会一直将自身的数据更新至slave。解决了master的读压力。

哨兵

redis sentinel 在分布式系统中,监控主从服务器,在master下线,会自动进行故障转移,保证了系统的高可用。

集群(proxy)

通过增加proxy层来进行数据分片,减轻redis的写压力。但是proxy层无法保证高可用,维护成本增加。

集群(直连型)

去除proxy层,无中心架构;通过选举制实现故障转移,完成slave到master的角色转换;节点可动态扩张;通过增加slave节点实现高可用;数据按照slot存储,节点数据可共享。

redis数据结构

redis以 key-value 键值对 作为存储方式。支持多种数据结构。

String
string是redis使用最多的数据结构之一,value大小不能超过512M,set的时候,可以不用引号。
值可以是字符串,整数,浮点数。
若值为数字,做运算时,redis会自动进行转换。

命令 说明
SET key value 定义key并赋值
GET key 获取key的值
DEL key 删除key
APPEND key value 末尾追加,字符串拼接
STRLEN key 获取字符串长度
INCR key 自增
DECR key 自减
INCRBY key increment 按指定步长增长
DECRBY key increment 按指定步长减少
SETEX key seconds value 同时设置过期时间,同EXPIRE,可使用TTL查看剩余时间

List
链表上的每个节点包含一个字符串。链表的两端都可以进行读写。

命令 说明
LPUSH key value 向链表左端添加元素value
RPUSH key value 向链表右端添加元素value
LPOP key 从链表左侧读取并移除元素
RPOP key 从链表右侧读取并移除元素
LINDEX key index 按index读取vaule
LRANGE key start stop 读取指定范围的元素
BRPOP key[key ...] timeout 阻塞的方式从链表右侧弹出元素,如果元素为空,阻塞等待,直到超时或者有值返回
BLPOP key[key ...] timeout 阻塞的方式从链表右侧弹出元素,如果元素为空,阻塞等待,直到超时或者有值返回

Set
无序且无重复的字符串集合

常用命令:

命令 说明
SADD key value 向key中添加元素value,成功返回1,失败返回0
SREM key value 从key中移除元素value,成功1,失败0
SMEMBERS key 列出key中所有元素
SISMEMBER key value 判断key中是否存在元素value,没找到0

zset
有序的set集合,通过浮点数score来实现。
元素a,b,若a.score>b.score,则a>b;若a.score=b.score,a>b,则a>b。

命令 说明
ZADD key score member 向key集合中插入memeber,设置score
ZRANGE key start stop 读取指定范围类元素
ZRANGEBYSCORE key min man 按照score的范围读取元素
ZREM key member 移除元素

hash
包含key,value的散列表。

命令 说明
HMSET key field value [field value ...] 添加值
HGET key field 取值
HMGET key field [field ...] 取值
HGETALL key 获取所有元素
HDEL key field [field ...] 删除指定字段

事务

因为redis是单线程来处理所有client的请求,所以redis对事务的处理比较简单,通过一个类似阻塞队列的东西保证一个client发起的事务中的命令可以顺序执行,中间不会插入其他client的命令。

通过 EXEC 命令来开启一个事务,DISCARD取消事务,EXEC结束事务

发布订阅

发布订阅(pub/sub)是类似观察者模式的一种消息通信模式,发送者(pub)发送消息,订阅者(sub)接收消息。

Redis特性解读_第1张图片
image.png-44.1kB

ps.网上找的图

SUBSCRIBE 订阅主题,开启通道,获取消息
PUBLISH 推送消息
UNSUBSCRIBE 取消主题

持久化

为了防止服务宕机内存数据丢失,redis提供了三种持久化方式:RDB(deafult),AOF,RDB和AOF同时使用。

RDB:

定时调用 rdbSave 函数,将内存数据写入一个dump.rdb,如果文件存在,替换。
操作 rdbSave 函数有两种命令,SAVE和BGSAVE
SAVE命令会直接调用rdbSave函数,在RDB文件保存期间,主进程会被阻塞,服务端无法处理客户端请求,保存完成,唤醒主线程。
BGSAVE命令会先fork一个子进程,由子进程调用 rdbSave 函数,不会阻塞主进程,服务端仍可服务客户端,保存完成,子进程会向主进程发送通知。
在redis服务启动或重启时,会调用 rdbLoad 函数,加载磁盘中的RDB文件到内存中。

+-------+-------------+-----------+-----------------+-----+-----------+
| REDIS | RDB-VERSION | SELECT-DB | KEY-VALUE-PAIRS | EOF | CHECK-SUM |
+-------+-------------+-----------+-----------------+-----+-----------+

                  |<-------- DB-DATA ---------->|
image.png-11.6kB
image.png-11.6kB

保存策略:
save 900 10 #900s内超过10个key被修改,发起快照保存。

AOF:
append-only-file,以协议(RESP)文本的方式,把数据库的命令操作参数追加到aof文件中。
这个过程分为三步:
1.命令传播:Redis 将执行完的命令、命令的参数、命令的参数个数等信息发送到 AOF 程序中。
2.缓存追加:AOF 程序根据接收到的命令数据,将命令转换为网络通讯协议的格式,然后将协议内容追加到服务器的 AOF 缓存中。
3.文件写入和保存:AOF 缓存中的内容被写入到 AOF 文件末尾,如果设定的 AOF 保存条件被满足的话, fsync 函数或者 fdatasync 函数会被调用,将写入的内容真正地保存到磁盘中。
AOF支持三种保存模式:
1.AOF_FSYNC_NO :不保存。
2.AOF_FSYNC_EVERYSEC :每一秒钟保存一次。(不阻塞主进程)
3.AOF_FSYNC_ALWAYS :每执行一个命令保存一次。(阻塞主进程)

参考文献 -- 《Redis设计与实现》

Redis特性解读_第2张图片
image.png-16.9kB

可以看到 rdb文件中存储的数据,aof文件中存储的是命令+数据,而且aof的文件可读性更高。
除此之外,AOF的更新频率高于RDB,优先加载aof。

复制

redis的复制方式有两种,一种是主(master)-从(slave),一种是从(slave)-从(slave)。

Redis特性解读_第3张图片
image.png-19.5kB

配置方式:

# 复制一份配置文件 cp redis.conf slave.conf
# 修改slave的配置 slaveof ip port
# 修改master的配置 bind 0.0.0.0
# 启动slave ./redis-server ../slave.conf &

集群

在redis集群中,引入了hash槽-slot的概念。
集群中的节点node,共同分配16384个slot,所以集群中节点最多只能有16384个,所有的key都对映射到对应的slot中。
redisCluster通过CRC16(key)/16384 来计算key属于哪个槽。

通过为每个node分片不同数量的slot,按照槽来分片,可以控制不同节点的数据量和请求数。

redisCluster的特点:
1.节点自动发现
2.slave->master 选举,集群容错
3.支持rehsard在线分片
4.节点直连型,不需要proxy层
5.所有节点彼此互连(ping-pong)

数据迁移

当我们需要新增节点时,只需要从以往节点中分配部分slot到新节点;需要删除节点时,先把该节点的slot转移到其他节点,然后删除即可。这个功能极大方便了集群的线性扩展或缩容,并不会造成集群不可用的状态。


Redis特性解读_第4张图片
image.png-14.4kB

在slot迁移过程中,masterA状态为MIGRATING,masterB状态为IMPORTING。
真正改变node映射的是键空间迁移。

src目录下的集群管理命令redis-trib.rb支持reshard的手动在线迁移方式。

命令 说明
call 在集群全部节点上执行命令
set-timeout 设置集群节点间心跳连接的超时时间
del-node 从集群中删除节点
reshard 在线迁移slot
check 检查集群
import 将外部redis数据导入集群
add-node 将新节点加入集群
create 创建集群
info 查看集群信息
fix 修复集群
rebalance 自动平分集群节点slot数量

你可能感兴趣的:(Redis特性解读)