Redis详解和主从架构原理实现
redis
- 简述
- redis的数据结构
- redis的数据持久化实现
- 程序与配置文件
- redis-cli命令
- 主从复制原理与架构实现
- redis的高可用方案 – sentinel
- redis分布式系统概述与简介
简述
什么是redis?
redis是一个基于nosql技术的kv数据库,支持非常大的并发场景,与memcached不同的是,redis拥有持久存储的能力,对数据的安全性有了保障,支持主从架构,并且虽然是单线程的,但却能够比拟memcached的性能。
redis的功能?
redis可以用来当作缓存服务器,消息队列。
memcached是将数据存放在内存中的,而redis则是定期存储到磁盘中,相对的磁盘IO还是会影响性能,并且redis是单线程,而memcached是多线程对多核心支持比较好。但是由于机制与优化得当redis的性能却能与memcached相当,真的还是非常出色的
redis的数据结构
redis一共有string,sets,zset,hash,list五种数据类型。
string:字符,值类似于 key value。sets:集合,值类似于 key value1 [value2 value3...]。sorted_set:有序的集合,值类似于 key score1 value1 [score2 value2 score2 value2....]。hash:哈希kv,值类似于 key field1 value1 [field2 values]。list:列表,值类似于集合,只不过采用采用了双向链表的方式,存取采用left与right两个方向的push与pop动作的方式。
redis的数据持久化实现
RDB
RDB的方式是使redis进程会按照事先定义的存储策略去将内存中的redis数据给存储到磁盘文件中。
- 有save与bgsave两种save方式,save在前台允许,而bgsave则运行在后台。
- save过程中,会施加写锁,所以会导致一定的服务不可用的状态。
- 由于存储的是实打实的数据,所以对磁盘空间的占用较合理。
AOF
AOF的方式是采用存储数据操作命令到磁盘来实现持久化,类似于mariadb的binary-log;
- AOF持久化通过重写(rewrite)的方式来实现。
- 重写过程中的写入请求不会影响重写,新的请求会被附加在原AOF文件后。
- 存储的是操作命令,所以对于磁盘占用较大,数据可以看作是伪数据。
rewrite流程:
1\. redis主进程去fork一个子进程用来读取当前的操作命令到临时文件存储。2\. 主进程会继续接受用户的写入操作,并且一方面附加到临时文件末尾,一方面存储到当前的AOF中。 #存储两份是为了防止子进程重写失败而导致一部分的写入数据丢失。3\. 子进程完成重写并且去替换原来的AOF文件,完成新的AOF文件存储。
> 1. 两种方案都有很明显的缺点,回想一下mariadb,其实采用RDB+AOF可以互补缺点。> 2. 持久存储并不能解决数据损坏的问题,所以我们其实还需要定期的对redis数据进程备份。## 程序与配置文件### 程序与文件
/etc/redis-sentinel.conf #redis的高可用组件sentinel的默认配置文件。/etc/redis.conf #redis的默认配置文件。/usr/bin/redis-cli #redis的命令行工具,支持远程连接到redis进行基于command的操作。/usr/bin/redis-sentinel #sentinel的主程序,实际上可以认为是是redis [option] <config-file> -sentinel的alias。/usr/bin/redis-server #redis的主程序,主要的格式redis [option] <config-file> 。/var/lib/redis #redis的默认库目录。/var/log/redis #redis的默认日志目录。/var/run/redis #redis的允许中产生的文件存放的默认目录。/usr/lib/systemd/system/redis-sentinel.service #sentinel的systemd文件。/usr/lib/systemd/system/redis.service #redis的systemd文件。
redis.conf的配置参数
#### GENERAL #### daemonize yes #以守护进程的方式运行pidfile "/var/run/redis/redis.pid" #pidfileport 6379 #porttcp-backlog 511 #tcp的backlog队列长度,backlog的长度是未建立的tcp连接和已经建立的tcp连接之和,等待进程从队列中调用建立的连接。bind 192.168.1.30 10.0.0.1 #监听的地址,可以指定多个,0.0.0.0代表本机所有所有地址。timeout 5000 #客户端连接的超时时间,单位是毫秒。loglevel notice #日志的记录等级。logfile "/var/log/redis/redis.log" #日志的存放位置。databases 16 #redis所启动的数据库(名称空间)数量,可以在cli中通过select #来切换。## SNAPSHOTTING ##save 900 1 #RDB方式的持久化策略,也就是说RDB方式下,数据被定期存储到磁盘的策略。save 300 10 #此处三个save依次表示,在900秒内,如果1个key发生改变就写一次磁盘;save 60 10000 #在300秒内,如果10个key发生改变就写一次磁盘;在60秒内如果10000个key发生改变就写一次磁盘。stop-writes-on-bgsave-error yes #在bgsave时,发生写入操作时会报告错误么,即在bgsave时不允许写入数据。rdbcompression yes #rdb文件可以被压缩。rdbchecksum yes #rdb文件开启校验。dbfilename "dump.rdb" #db的名称为 dump.rdbdir "/redis/data1" #RDB的数据目录,在指定非默认目录时,需要修改目录的属主属组为你当前redis进程的属主属组,一般为redis。# APPEND ONLY MODE #appendonly yes #开启AOF持久化方式。appendfilename "appendonly.aof" #AOF文件名。appendfsync everysec #AOF的持久化策略,有三个值,always表示只要发生数据操作就执行保存或者重写AOF;everysec表示一秒一次;no表示关闭;no-appendfsync-on-rewrite yes #在重写时将当前AOF的日志存储在内存中,防止AOF附加操作与重写产生数据写入堵塞问题,提高了性能却增加了数据的风险性。auto-aof-rewrite-percentage 100 #每当AOF日志是上次重写的一倍时就自动触发重写操作。auto-aof-rewrite-min-size 64mb #自动触发重写的最低AOF日志大小为64MB,为了防止在AOF数据量较小的情况话频繁发生重写操作。aof-load-truncated yes #当redis发生奔溃,通过AOF恢复时,不执行最后最后那条因为中断而发生问题的语句。#### LIMITS ####maxclients 10000 #限制最大的并发用户连接数为10000条。# maxmemory <bytes> #限制最大的内存使用量。### SECURITY ###requirepass <password> #设定认证的密码,如果设定了,在远程cli登录,主从配置和sentinel时都需要指定对应参数为此passwd。
redis-cli命令
redis-cli [-h <hostname> -p <port> -a <password>]@genericDEL KEYS(KEYS *列出所有键) MOVE ...@serverSYNC SLAVEOF SAVE BGSAVE SHUTDOWN ... (CLIENT ... CONFIG ...)@connectionAUTH(认证) ECHO PING QUIT SELECT(切换数据库) ...@stringGET SET INCR(+1) DECR(-1) SETNX STRLEN ...@list LINDEX LINSERT LLEN LPOP LPUSH LPUSHX LRANGE LSET RPOP RPUSH RPUSHX(值不存在才设置) ...@setSADD SCARD SMEMBERS(get值) SRANDMEMBER(随机get值) SDIFF(求差异) SDIFFSTORE SINTER(交集) SINTERSTORE SUNION(并集) SUNIONSTORE ...@sorted_setZADD ZCARD ZCOUNT(返回有序集中range间的所有值) ZSCORE(根据序号get值) ...@hashHDEL HGET HGETALL HINCRBY HKEYS HSET HSETNX ...
> 详细的cli命令可以自行通过搜索引擎,命令行帮助help或者官方文档来仔细查阅,本文由于篇幅问题就列出了一部分命令组中常用的命令,命令格式也请自行查阅。## 主从复制原理与架构实现![redis-replicaiton架构](https://wanggaoli.com/wp-content/uploads/2016/08/redis-replicaiton架构.png)![redis-replicaiton](https://wanggaoli.com/wp-content/uploads/2016/08/redis-replicaiton.png)### 配置过程
# redis-cli -h 192.168.1.30 -p 6379 192.168.1.30> SLAVEOF 192.168.1.29 6379 #只需一条命令就可以实现。详细命令可以参考help SLAVEOF。 OK! 192.168.1.30> INFO ...... #Repocation ...... slave0:ip=192.168.1.30,port=6379,state=online.... #可以很清楚的看到slave信息和master信息,此处就不再详述。
redis.conf中replication的几个主要参数
### REPLICATION ###slaveof 192.168.1.29 6379 #主节点地址,<host> <port>。#masterauth <master-password> #如果设置了访问认证就需要设定此项。slave-server-stale-data yes #当slave与master连接断开或者slave正处于同步状态时,如果slave收到请求允许响应,no表示返回错误。slave-read-only yes #slave节点是否为只读。slave-priority 100 #设定此节点的优先级,是否优先被同步。
redis的高可用方案 – sentinel
主从复制架构中,如果主节点产生故障,那么整个redis系统都会瘫痪,为了解决这个单点,对主节点的高可用就是非常有必要的,redis自带的sentinel,就能很好的解决redis的高可用问题,通过ping机制检测节点状态,并且帮助主节点转移;
sentinel是一个第三方节点来监理而解决高可用的方案,第三方的一台或多台节点共同判定投票主节点的状态并且是否转移。
配置过程
# vim /etc/redis-sentinel.conf port 26379 #sentinel announce-ip 1.2.3.4 #默认监听在0.0.0.0 所以此处可以注释。 dir "/tmp" sentinel monitor mymaster 192.168.1.29 6379 1 #sentinel moitor <master-name> <ip> <redis-port> <法定人数quorum> #设定master节点的*名称*和位置,法定人数表示多少台sentinel节点认同才可以上线。 sentinel down-after-milliseconds mymaster 5000 #如果联系不到节点5000毫秒,我们就认为此节点下线。 sentinel failover-timeout mymaster 60000 #设定转移主节点的目标节点的超时时长。 sentinel auth-pass <master-name> <password> #如果redis节点启用了auth,此处也要设置password。# redis-sentinel /etc/redis-sentinel.conf# ss-tnl | grep 26379 LISTEN 0 128 *:26379 *:* users:(("redis-sentinel",3099,5)) LISTEN 0 128 :::26379 :::* users:(("redis-sentinel",3099,4))
cli中的sentinel组命令
sentinel master <master-name> #查看此复制集群的主节点信息。sentinel slaves <master-name> #查看此复制集群的从节点信息。sentinel failover <node-name> #切换指定的节点为节点为主节点。
redis分布式系统概述与简介
redis与mariadb,mongodb一样,在海量数据的情况下,复制已经无法解决性能压力,这时候我们就需要通过分片机制分割数据,构建分布式系统;接下来我们就来粗略的看一下分布式redis的架构与解决方案。
分布式redis架构图
与mariadb和mongodb类似,请求到分片路由节点,之后由路由节点智能的分配到相对的数据节点,并且要考虑到结构的可靠性的高可用方案,同样的需要符合分布式系统的cap和base标准;并且还要考虑到数据怎么分片的问题,所以说较为复杂。
解决方案
twemproxy
是由推特开发的,中心化的,基于ping来监控的的redis分布式解决方案,由于不支持路由节点高可用,不能平滑升级,只有cli接口,所以现在已经不是很推荐使用了。
codis(较为推荐的解决方案)
是由豆瓣开发的强一致性的,强依赖zookeep,中心化,加入了路由节点高可用方案,基于pingpong来监控各节点,支持平滑升级,有web gui接口,不支持读写分离的redis高可用解决方案。
分布式redis系统,本文只是写了大概的介绍,深入的可以自行了解,由于是国人开发的,所以文档资料什么的还是很友好的;并由于分布式redis是在较大规模的场景下才需要的架构,一般的中小型场景中其中的复制子系统就够用了。
文中所有图片都为作者本人自行绘制。
转自:http://www.178linux.com/37667