redis主从架构(上)

  • 2019 年 11 月 12 日
  • 筆記

1、redis概述

redis的出现时间并不长,是NoSQL中的一种,基于键-值型的存储,与memcache类似,但是memcache中只是内存的缓存,而redis不仅是内存中的缓存,还提供持久存储,在2009年第一次发布redis。

Redis 全称(REmote DIctionary Server)远程字典服务器,而这个字典服务器从本质上来讲,主要是提供数据结构的远程存储功能的,可以理解为redis是一个高级的K-V存储,和数据结构存储,因为redis除了能够存储K-V这种简单的数据之外,还能够存储,列表、字典、hash表、等对应的数据结构。

2、Redis与Memcache对比

1.是一个分布式的内存对象缓存系统,而redis是可以实现持久存储。

2.Memcache是一个LRU的缓存,redis支持更多的数据类型。

3.Memcache是多线程的,redis是单线程的。

4.二者性能几乎不相上下,实际上redis会受到硬盘持久化的影响,但是性能仍然保持在与Memcache不相上下,是非常了不起的。

3、redis与memcache的不同之处

在性能上redis不比memcache差,因为redis整个运行通通都是在内存中实现的,它的所有的数据集都是保存在内存中的,内存中的数据会周期性的写入到磁盘上,以实现数据的持久功能,而这种写磁盘并不是用于访问,而仅是冗余功能,所以redis所有功能都在内存中完成,因为此性能也是可想而知。

redis与mamcache不同之处在于redis有一个周期性的将数据保存到磁盘上的机制,而且不只一种,有两种机制,这也是redis持久化的一种实现,另外与mamcache有所区别的是,redis是单线程服务器,只有一个线程来响应所有的请求。

4、redis主从模式

redis支持主从模式,但是redis的主从模式默认就有一个sentinel工具,从而实现主从架构的高可用,也就是说,redis能够借助于sentinel工具来监控主从节点,当主节点发生故障时,会自己提升另外一个从节点成为新的主节点。

在redis 3.0版本发布,开始支持redis集群,从而可以实现分布式,可以将用户的请求分散至多个不同节点。

5、redis所支持的数据类型

支持存储的数据类型有:String(字符串,包含整数), List(列表), Hash(关联数组), Sets(集合), Sorted Sets(有序集合), Bitmaps(位图), HyperLoglog

6、redis性能评估

1.100万较小的键存储字符串,大概消耗100M内存。

2.由于redis是单线程,如果服务器主机上有多个CPU,只有一个能够使用,但并不意味着CPU会成为瓶颈,因为redis是一个比较简单的K-V数据存储,CPU通常不会成为瓶颈的。

3.在常见的linux服务器上,500K(50万)的并发,只需要一秒钟处理,如果主机硬件较好的情况下,每秒钟可以达到上百万的并发。

7.1Redis的优势

1.丰富的(资料形态)操作:String(字符串,包含整数), List(列表), Hash(关联数组), Sets(集合), Sorted Sets(有序集合), Bitmaps(位图), HyperLoglog。

2.内建Replication和culster(自身支持复制及集群功能)。

3.支持就地更新(in-place update)操作,直接可以在内存中完成更新操作。

4.支持持久化(磁盘)避免雪崩效应,万一出现雪崩效应,所有的数据都无法恢复,但redis由于有持久性的数据,可以实现恢复。

7.2Memcached的优势

1.多线程

2.善用多核CPU

3.更少的阻塞操作

4.更少的内存开销

5.更少的内存分配压力

6.可能有更少的内存碎片

8、redis主从搭建

主redis:172.17.0.53

从redis:172.17.0.54

8.1编译安装

 [root@docker-02 ~]# wget http://download.redis.io/releases/redis-4.0.10.tar.gz   [root@docker-02 ~]# tar xzf redis-4.0.10.tar.gz   [root@docker-02 ~]# cd redis-4.0.10/src   [root@docker-02 src]# make PREFIX=/usr/local/redis install

8.2创建目录

 [root@docker-02 src]# mkdir -p /usr/local/redis/conf   [root@docker-02 src]# mkdir -p /usr/local/redis/data   [root@docker-02 src]# mkdir -p /usr/local/redis/logs

redis/

├── bin redis二进制文件路径

├── conf 存放配置

├── data 存放数据

└── logs 存放日志/pid文件

8.3创建redis用户

 [root@docker-02 src]# useradd -s /sbin/nologin redis   [root@docker-02 src]# chown -R redis.redis /usr/local/redis/

8.4配置standalone单机模式

 ##配置文件没有,自己创建配置文件   [root@docker-02 src]# vim /usr/local/redis/conf/redis_6301.conf   ##6301##   ################################## NETWORK #####################################   bind 0.0.0.0   protected-mode yes ##daemonize no Linux Shell终端运行redis,改为yes即后台运行Redis服务   port 6301   tcp-backlog 511 ## 在高并发的环境中,为避免慢客户端的连接问题,需要设置一个高速后台日志   timeout 0 ## bind 0.0.0.0#设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接   tcp-keepalive 300 ## 在Linux 上,指定值(秒)用于发送 ACKs 的时间。注意关闭连接需要双倍的时间。默认为 0   ################################# GENERAL #####################################   daemonize yes ##redis采用的是单进程多线程的模式。当redis.conf中选项daemonize设置成yes时,代表开启守护进程模式。在该模式下,redis会在后台运行,并将进程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将一直运行,除非手动kill该进程。   supervised no  ##可以通过upstart和systemd管理Redis守护进程   pidfile /usr/local/redis/logs/6301.pid  ## 当运行多个 redis 服务时,需要指定不同的pid文件和端口   loglevel notice  ##设置服务端的日志级别   logfile /usr/local/redis/logs/6301.log   databases 16 ##数据库的总数,默认16个   always-show-logo yes ##是否总是显示logo   ################################ SNAPSHOTTING ################################   save 9001   save 30010   save 6010000   stop-writes-on-bgsave-error yes ## 默认情况下,如果 redis 最后一次的后台保存失败,redis 将停止接受写操作   rdbcompression yes ## 是否在 dump .rdb 数据库的时候使用 LZF 压缩字符串   rdbchecksum yes ## 是否校验rdb文件   dbfilename dump6301.rdb  ## 设置 dump 的文件位置   dir /usr/local/redis/data/  ## 工作目录   ################################# REPLICATION #################################   # slaveof <masterip> <masterport>   # masterauth <master-password>   slave-serve-stale-data yes ## 当一个 slave 与 master 失去联系,或者复制正在进行的时候,slave 可能会有两种表现   如果为 yes,slave 仍然会应答客户端请求,但返回的数据可能是过时,   如果为 no ,在你执行除了 info he salveof 之外的其他命令时,slave 都将返回一个 "SYNC with master in progress"的错误   slave-read-only yes ## slave 实体是否接受写入操作,从 redis 2.6 版起,默认 slaves 都是只读的   repl-diskless-sync no  ##硬盘备份   repl-diskless-sync-delay 5   repl-disable-tcp-nodelay no   slave-priority 100 ##如果 master 不能再正常工作,那么会在多个 slave 中,选择优先值最小的一个 slave 提升为 master   优先值为 0表示不能提升为 master   ################################## SECURITY ###################################   requirepass rds6301_paswd  ## 设置认证密码   ################################### CLIENTS ####################################   maxclients 10000 ## 最大限制   ############################## MEMORY MANAGEMENT ################################   maxmemory 8gb  ## 最大使用内存   maxmemory-policy volatile-lru  ##内存不足"时,数据清除策略,默认为"volatile-lru"   ############################# LAZY FREEING ####################################   lazyfree-lazy-eviction no  ##内存满逐出选项   lazyfree-lazy-expire no   lazyfree-lazy-server-del no   slave-lazy-flush no  ##全量同步时,slave异步清空所有DB   ############################## APPEND ONLY MODE ###############################   appendonly yes ##以追加的方式记录所有写操作   appendfilename "appendonly6301.aof" ##配置设置   appendfsync everysec  ##异步操作,每秒记录 如果有一秒内宕机,有数据丢失   no-appendfsync-on-rewrite no   auto-aof-rewrite-percentage 100 ##当aof log增长超过指定比例时,重写log file, 设置为0表示不自动重写Aof 日志,重写是为了使aof体积保持最小,而确保保存最完整的数据。   auto-aof-rewrite-min-size 64mb  ##触发aof rewrite的最小文件尺寸   aof-load-truncated yes   aof-use-rdb-preamble no  ##配置项可以打开混合开关   ################################ LUA SCRIPTING ###############################   lua-time-limit 5000 ##最大执行时间的长短   ################################ REDIS CLUSTER ###############################   ########################## CLUSTER DOCKER/NAT support ########################   ################################## SLOW LOG ###################################   slowlog-log-slower-than 10000 ## 可以通过两个参数设置 slow log :一个是告诉 Redis 执行超过多少时间被记录的参数 slowlog-log-slower-than( 微秒 ) 另一个是 slow log 的长度。当一个新命令被记录的时候最早的命令将被从队列中移除   上面的时间以微秒为单位,因此 1000000代表一秒。注意指定一个负数将关闭慢日志,而设置为 0将强制每个命令都会记录   slowlog-max-len 128 ##对日志长度没有限制,只是要注意它会消耗内存   可以通过 SLOWLOG RESET 回收被慢日志消耗的内存   推荐使用默认值 128,当慢日志超过 128时,最先进入队列的记录会被踢出   ################################ LATENCY MONITOR ##############################   latency-monitor-threshold 0 ##默认情况下延时监控   ############################# EVENT NOTIFICATION ##############################   notify-keyspace-events "" ##开启或关闭键空间通知功能   ############################### ADVANCED CONFIG ###############################   hash-max-ziplist-entries 512 ##filed最多512个   hash-max-ziplist-value 64 ##value最大64字节   list-max-ziplist-size -2 ##取正值时表示quicklist节点ziplist包含的数据项   list-compress-depth 0 ##0: 是个特殊值,表示都不压缩   set-max-intset-entries 512 ##如 type 是 REDIS_SET 类型的,如果其值可以表示成数字类型且 entry 小于配置值set-max-intset-entries, 则可以编码成 REDIS_ENCODING_INTSET 类型存储,以节约内存; 否则采用 Dict类型来存储   zset-max-ziplist-entries 128 ##相同的hash列表中,排序列表的元素和长度都不能高于如下值   zset-max-ziplist-value 64   hll-sparse-max-bytes 3000   activerehashing yes ##重建hash表的时候如果内存不足 如果此值设置为no则延时,如果为yes则尽快释放内存   client-output-buffer-limit normal 000 ##客户端buffer限制,如果达到硬限制则立刻断开   client-output-buffer-limit slave 256mb 64mb 60   client-output-buffer-limit pubsub 32mb 8mb 60   hz 10 ##一个任务可以使用的cpu数目   aof-rewrite-incremental-fsync yes ##当一个子进程要改写AOF文件,如果以下选项启用,那文件将会在每产生32MB数据时进行同步,这样提交增量文件到磁盘时可以避免出现比较大的延迟   ########################### ACTIVE DEFRAGMENTATION #######################

8.5配置slave从模式

主从配置文件一样,从库只需要加几个配置即可

 ########################### ACTIVE DEFRAGMENTATION #######################   ################################# REPLICATION #################################   slaveof 172.17.0.53 6306#主服务器redis的ip和端口   masterauth rds6301_paswd   slave-read-only yes

8.6启动redis实例

 [root@docker-02 redis]# /usr/bin/sudo -H -u redis -g redis /bin/bash -c "/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis_6301.conf"   [root@docker-02 redis]# ps -ef|grep 6301   redis    32013    1 016:00 ?        00:00:00 /usr/local/redis/bin/redis-server 0.0.0.0:6301   root     3201831963 016:00 pts/0    00:00:00 grep--color=auto 6301

一般redis都是单机多实例部署,只需要替换配置文件中的端口相关的配置即可,

appendonly 和 SNAPSHOTTING 可以都开启或只开启一个即可根据实际需求决定 。

8.7查看状态

 [root@docker-02 bin]# /usr/local/redis/bin/redis-cli -p 6301 -a rds6301_paswd info   ##可以看到从的状态信息   # Replication   role:slave   master_host:172.17.0.53   master_port:6306   master_link_status:up   master_last_io_seconds_ago:3   master_sync_in_progress:0   slave_repl_offset:718410   slave_priority:100   slave_read_only:1   connected_slaves:0   master_replid:d40bce93544a3a66c6afc01081fe851a4ccf278d   master_replid2:0000000000000000000000000000000000000000   master_repl_offset:718410   second_repl_offset:-1   repl_backlog_active:1   repl_backlog_size:1048576   repl_backlog_first_byte_offset:1   repl_backlog_histlen:718410

9、redis基本操作

 ##登录到redis   [root@docker-02 ~]# /usr/local/redis/bin/redis-cli -p 6301 -a rds6301_paswd   ##获取使用帮助   127.0.0.1:6301> help  ##redis的help命令非常强大,因为redis支持众多的数据结构,每一种数据结构当中都支持N种操作,因此需要使用 help @group方式来1.获取某一种数据结构所支持的操作2.获取字符串组所支持有那些操作   127.0.0.1:6301> help @string   ##获取单个命令的使用方法   127.0.0.1:6301> help APPEND   APPEND key value  ##命令方法   summary: Append a value to a key   since: 2.0.0  ##说明此命令在哪个版本中引入的   group: string  ##该命令所属哪一个组   ##查看都有哪些组   127.0.0.1:6301> help TAB键,每敲一次轮换一个,带有@则为一个组,不带@则为命令使用   ##切换库(名称空间)   127.0.0.1:6301> select 1 ##表示切换到1号库中,默认为0号库,共16个,0-15

10、键的遵循

1.可以使用ASCII字符

2.键的长度不要过长,键的长度越长则消耗的空间越多

3在同一个库中(名称空间),键的名称不得重复,如果复制键的名称,实际上是修改键中的值

4.在不同的库中(名称空间),键的同一个名称可以重复

5.键可以实现自动过期

11、Strings的操作

 127.0.0.1:6301[1]> help set   SET key value [EX seconds] [PX milliseconds] [NX|XX]  ##命令 键 值 [EX 过期时间,单位秒]   summary: Set the string value of a key   since: 1.0.0   group: string   ##NX:如果一个键不存在,才创建并设定值,否则不允许设定   ##XX:如果一个键存在则设置键的值,如果不存在则不创建并不设置其值   127.0.0.1:6301[1]> setywm lzll   OK   127.0.0.1:6301[1]> setywm aaa NX  ##反回提示一个没能执行的操作   (nil)   127.0.0.1:6301[1]> getywm   "lzll"   127.0.0.1:6301[1]> setywm abc XX   OK   ##定义一个键并设置过期时间为60秒   127.0.0.1:6301[1]> setywm bcd EX 60   OK

12、获取键中的值

 127.0.0.1:6301[1]> help get   GET key   summary: Get the value of a key   since: 1.0.0   group: string   127.0.0.1:6301[1]> setmxp lzll   OK   127.0.0.1:6301[1]> getmxp   "lzll"   ##添加键中的值(在原有键中附加值的内容)   127.0.0.1:6301[1]> append mxp fda   (integer) 7   127.0.0.1:6301[1]> getmxp   "lzllfda"   ##获取指定键中的值的字符串的长度   127.0.0.1:6301[1]> strlen mxp   (integer) 7

13、定义整数值

 127.0.0.1:6301[1]> setywm 0 ##整数值为0   OK   ##增加键中的整数值   127.0.0.1:6301[1]> incr ywm   (integer) 1   127.0.0.1:6301[1]> incr ywm   (integer) 2   127.0.0.1:6301[1]> incr ywm   (integer) 3   127.0.0.1:6301[1]> incr ywm   (integer) 4   127.0.0.1:6301[1]> getywm   "4"   注:incr命令只能对整数使用

14、删除键

 127.0.0.1:6301[1]> del ywm   (integer) 1   127.0.0.1:6301[1]> getywm   (nil)

15、列表的操作

键指向一个列表,而列表可以理解为是一个字符串的容器,列表是有众多元素组成的集合,可以在键所指向的列表中附加一个值

1.LPUSH 在键所指向的列表前面插入一个值(左边加入)

2.RPUSH 在键所指向的列表后面附加一个值(右边加入)

3.LPOP 在键所指向的列表前面弹出一个值(左边弹出)

4.RPOP 在键所指向的列表后面弹出一个值(右边弹出)

5LINDEX 根据索引获取值,指明索引位置进行获取对应的值

6.LSET 用于修改指定索引的值为指定的值

 ##指定一个新的列表,在帮助中并没说明哪个命令用于创建一个新的列表,实际上创建一个新的列表使用LPUSH或RPUSH都可以   127.0.0.1:6301[1]> help @list   127.0.0.1:6301[1]> lpush ll cjk  ##ll为列表名称,cjk为值(索引)   (integer) 1   ##获取列表中的值:需要指明索引位置进行获取对应的值   127.0.0.1:6301[1]> lindex ll 0 ##第一个索引则为0   "cjk"   ##在原有的列表中的左侧加入一个值   127.0.0.1:6301[1]> lpush ll 0   (integer) 3   127.0.0.1:6301[1]> lpush ll 1   (integer) 4   127.0.0.1:6301[1]> lindex ll 0   "1"   127.0.0.1:6301[1]> lindex ll 1   "0"   ##在原有的列表中的右侧加入一个值   127.0.0.1:6301[1]> rpush ll lzll   (integer) 7   127.0.0.1:6301[1]> lindex ll 6   "lzll"   ##修改一个已有的列表中的值   127.0.0.1:6301[1]> lset ll 6abc   OK   127.0.0.1:6301[1]> lindex ll 6   "abc"   ##查看列表中的值的数量   127.0.0.1:6301[1]> llen ll   (integer) 7   ##在已有的列表中右侧弹出(删除)一个值   127.0.0.1:6301[1]> rpop ll   "abc"   ##在已有的列表中左侧弹出(删除)一个值   127.0.0.1:6301[1]> lpop ll   "1"   127.0.0.1:6301[1]> lpop ll   "0"   127.0.0.1:6301[1]> lpop ll   "fda"

16、清空数据库

 ##FLUSHDB:删除当前选择的数据库所有key   ##FLUSHALL:清空所有库   127.0.0.1:6301[1]> flushdb   OK