10.1 redis的运行方式说明
redis如果提供缓存服务,可以关闭所有持久化存储,如此一来redis重启后所有数据会丢失 开启rdb或aof持久化存储,能把redis中的数据持久化到磁盘中。 rdb和aof对性能都有影响,所以建议持久化的操作在从库上进行10.2 redis rdb存储方式,使用save配置开启rdb存储或者关闭rdb存储
[root@redis01 ~]# cat /usr/local/redis/conf/redis.conf #与rdb相关的配置文件信息 root@redis01 ~]# cat -n /usr/local/redis/conf/redis.conf | sed -n "14p;15p;16p;18p;20p;21p" 14 save 900 1 #900s改变1个key(写入一条数据)触发rdb存储 15 save 300 10 #300s改变10个key(写入一条数据),触发rdb存储 16 save 60 10000 #60s改变10000key(写入一条数据),触发rdb存储 18 rdbcompression no #rdb压缩最好关闭,影响cpu性能 20 dbfilename "dump.rdb"#rdb存储文件的名字 21 dir "/data/redis"#dir为rdb存储的路径 说明: 首先,redis触发存储,如果太频繁,显然影响应能,redis单进程+单线程接待用户(异步非阻塞模型),所有用户时一个线程接待的,单线程没有了冲突问题。最大化降低冲突问题。但是,这个单线程很怕大文件,耗时大的。而且,单线程很容易造成阻塞,如果太频繁的存储。会极大地影响数据写入的性能。rdb是一种兼顾性能和数据安全的一种存储方式。redis不忙的时候,900秒触发一次存储。如果忙起来,300秒,10触发一次。60秒 1万条数据,我才触发一次。10.3 设置开启或者关闭rdb存储
提示:默认情况下rdb持久化存储是开启的 [root@redis01 ~]# redis-cli config set save "" #关闭rdb存储 OK [root@redis01 ~]# redis-cli config rewrite #配置保存 OK [root@redis01 ~]# redis-cli config set save "180 1 120 10 60 10000" #开启rdb OK [root@redis01 ~]# redis-cli config rewrite OK 官方推荐开启的方式就是rdb,最小程度影响性能。 redis是数据库缓存。为的是降低数据库从库的读压力。为何memcached会被redis淘汰。本质就是持久化存储。但是,刚一开启memcached的时候,里面没有数据。此时大量用户请求都要找数据库从库。很可能引起数据库崩溃。所以,以前在用memcached时候,一旦memcached重启,现需要一个步骤叫做预热。才能正式启用。redis不需要这个。他有持久化方式。就算丢。丢的也是那一小部分。 有些数据只存redis,不存在数据库里。例如:一个网站统计的时时在线人数。10.4 进行数据写入,观察rdb存储日志
#输入1万条数据 [root@redis01 ~]# for line in `seq -w 10000`;do redis-cli set key_${line} value1_${line};done#查看日志信息
[root@redis01 ~]# cat /data/redis/redis.log
26094:M 14 Apr 21:36:20.247 # Server initialized
26094:M 14 Apr 21:36:20.248 * DB loaded from disk: 0.000 seconds
26094:M 14 Apr 21:36:20.248 * Ready to accept connections
26094:M 14 Apr 21:37:16.399 # CONFIG REWRITE executed with success.
26094:M 14 Apr 21:37:30.709 # CONFIG REWRITE executed with success.
26094:M 14 Apr 21:39:50.374 * 1 changes in 180 seconds. Saving...#发生了1万条数据改变180秒内,触发rdb存储
26094:M 14 Apr 21:39:50.375 * Background saving started by pid 26289 #生成一个子进程触发RDB
26289:C 14 Apr 21:39:50.382 * DB saved on disk
26289:C 14 Apr 21:39:50.382 * RDB: 0 MB of memory used by copy-on-write
26094:M 14 Apr 21:39:50.475 * Background saving terminated with success
#查看redis里有多少个键值(keys)
[root@redis01 ~]# redis-cli info
......省略......
# Keyspace
db0:keys=10055,expires=0,avg_ttl=0
#redis占用了多少内存 [root@redis01 ~]# redis-cli info memory # Memory used_memory:1702592 #数据占用内存大小 used_memory_human:1.62M #人性化的方式显示数据占用内存大小 used_memory_rss:3239936 #数据和进程占用大小 used_memory_rss_human:3.09M #人性化的方式显示数据和进程占用大小 used_memory_peak:1703568 used_memory_peak_human:1.62M used_memory_peak_perc:99.94% used_memory_overhead:1369526 used_memory_startup:786592 used_memory_dataset:333066 used_memory_dataset_perc:36.36% total_system_memory:1021906944 total_system_memory_human:974.57M used_memory_lua:37888 used_memory_lua_human:37.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:1.90 #redis碎片率(频繁的写入删除,就会产生碎片,删的越多碎片就会越高),1-2之间代表没有内存碎片,小于1说明已经占用虚拟缓存,分配的内存不够用了 mem_allocator:jemalloc-4.0.3 active_defrag_running:0 lazyfree_pending_objects:010.5 redis提供的bgsave命令能够立刻触发rdb存储,观察存储日志
[root@redis01 ~]# redis-cli save #直接占用主进程,会阻塞前端客户数据输入 ok [root@redis01 ~]# redis-cli bgsave #后台启动新进程进行rdb存储(不影响前端输入) Background saving started#查看日志 [root@redis01 ~]# cat /data/redis/redis.log 26094:M 14 Apr 21:53:08.882 * DB saved on disk #save触发的日志信息 26094:M 14 Apr 21:53:13.450 * Background saving started by pid 36961 #bgsave触发的信息 36961:C 14 Apr 21:53:13.464 * DB saved on disk #bgsave触发的信息 36961:C 14 Apr 21:53:13.465 * RDB: 0 MB of memory used by copy-on-write #bgsave触发的信息 26094:M 14 Apr 21:53:13.474 * Background saving terminated with success #bgsave触发的信息
十一,Redis的AOF存储方式
redis的appendonly(aof)持久化存储会把用户每次的操作都记录到文件中(类似mysqlbinlog)
11.1 动态开启或者关闭aof
[root@redis01 ~]# redis-cli config set appendonly yes #开启 OK [root@redis01 ~]# redis-cli config rewrite OK [root@redis01 ~]# redis-cli config get appendonly #查询状态 1) "appendonly" 2) "yes" [root@redis01 ~]# redis-cli config set appendonly no OK [root@redis01 ~]# redis-cli config rewrite OK11.2 写入数据,观察aof。多次运行,aof文件不断增大,rdb文件大小不变
#查看aof和rdb文件大小 [root@redis01 ~]# du -sh /data/redis/appendonly.aof 464K /data/redis/appendonly.aof [root@redis01 ~]# du -sh /data/redis/dump.rdb 236K /data/redis/dump.rdb #写入数据 [root@redis01 ~]# for line in `seq -w 100`;do redis-cli set key_${line} value_${line};done #查看aof和rdb文件大小 [root@redis01 ~]# redis-cli config set appendonly yes OK [root@redis01 ~]# redis-cli config rewrite OK [root@redis01 ~]# du -sh /data/redis/appendonly.aof 468K /data/redis/appendonly.aof [root@redis01 ~]# du -sh /data/redis/dump.rdb 236K /data/redis/dump.rdb11.3 重写aof文件,整理相同的key,写入最后的有效值
BGREWRITEAOF
执行一个AOF文件重写操作。重写会创建一个当前AOF文件的体积优化版本 即使BGREWRITEAOF执行失败,也不会有任何数据丢失,因为旧的AOF文件在BGREWRITEAOF成功之前不会被修改。 重写操作只会在没有其他持久化工作在后台执行时被触发。 从Redis2.4开始,AOF重写由Redis自行触发,BGREWRITEAOF仅仅用于手动触发重写操作。 #清空aof文件 [root@redis01 ~]# > /data/redis/appendonly.aof [root@redis01 ~]# du -sh /data/redis/appendonly.aof 0 /data/redis/appendonly.aof [root@redis01 ~]# redis-cli bgrewriteaof #手动触发AOF重写 Background append only file rewriting started [root@redis01 ~]# du -sh /data/redis/appendonly.aof #redis里所有数据被重写入aof 468K /data/redis/appendonly.aof#清空aof文件
[root@redis01 ~]# > /data/redis/appendonly.aof
[root@redis01 ~]# du -sh /data/redis/appendonly.aof
0 /data/redis/appendonly.aof
[root@redis01 ~]# redis-cli set yunjisuan benet
OK
[root@redis01 ~]# du -sh /data/redis/appendonly.aof
4.0K /data/redis/appendonly.aof
[root@redis01 ~]# cat /data/redis/appendonly.aof
*2
$6
SELECT #select 0 表示切换到db0
$1
0
*3
$3
set #执行set yunjisuan benet
$9
yunjisuan
$5
benet
[root@redis01 ~]# redis-cli del yunjisuan benet
(integer) 1
[root@redis01 ~]# cat /data/redis/appendonly.aof
*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文件就小很多了。
11.4 aof配置自动rewrite机制
#在默认配置文件里,默认存在 [root@redis01 ~]# redis-cli config get auto-aof-rewrite* #获取aof-rewrite配置 1) "auto-aof-rewrite-percentage" 2) "100" #默认100%,也就是aof增加一倍后考虑rewrite,两个条件要同时满足 3) "auto-aof-rewrite-min-size" 4) "67108864" #默认64mb,也就是aof达到64M后考虑rewirte,两个条件要同时满足#进行aof自动重写测试
[root@redis01 ~]# redis-cli config set auto-aof-rewrite-min-size 100000
OK
[root@redis01 ~]# 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-cli config rewrite
OK
[root@redis01 ~]# > /data/redisappendonly.aof
[root@redis01 ~]# du -sh /data/redis/appendonly.aof
4.0K /data/redis/appendonly.aof
[root@redis01 ~]# for line in `seq -w 1000`;do redis-cli set key2_${line} value2_${line};done
[root@redis01 ~]# du -sh /data/redis/appendonly.aof
48K /data/redis/appendonly.aof
[root@redis01 ~]# for line in `seq -w 1000`;do redis-cli set key2_${line} value2_${line};done
[root@redis01 ~]# du -sh /data/redis/appendonly.aof
128K /data/redis/appendonly.aof
[root@redis01 ~]# du -sh /data/redis/appendonly.aof
92K /data/redis/appendonly.aof #自动触发了aof重写机制
十二,Redis最大内存设置和删除算法 [root@redis01 ~]# redis-cli flushall #手动清空redis里所有数据 OK [root@redis01 ~]# redis-cli 127.0.0.1:6379> keys * (empty list or set)12.1 redis的键设置有效期,过期自动删除
redis对于数据过期的处理方式,取决于它的内存过期算法 [root@redis01 ~]# redis-cli set name yunjisuan OK [root@redis01 ~]# redis-cli ttl name (integer) -1 #-1代表key永久有效 [root@redis01 ~]# redis-cli expire name 10 #设定key 10s有效 (integer) 1 [root@redis01 ~]# redis-cli ttl name #查看key存活剩余时间 (integer) 3 [root@redis01 ~]# redis-cli ttl name (integer) 1 [root@redis01 ~]# redis-cli ttl name (integer) 0 [root@redis01 ~]# redis-cli ttl name (integer) -2 #说明已经被过期清除了 [root@redis01 ~]# redis-cli get name (nil) #key已经被过期清除了12.2 查看设置最大内存
#查看和设定最大内存限制 [root@redis01 ~]# redis-cli config get maxmemory 1) "maxmemory" 2) "0" #默认对内存无限制 [root@redis01 ~]# redis-cli config set maxmemory 1M #限制1M OK [root@redis01 ~]# redis-cli config get maxmemory 1) "maxmemory" 2) "1000000"12.3 可选择的删除算法
olatile-lru:使用LRU算法删除键(key需要设置过期时间)
volatile-random:随机删除键(key需要设置过期时间)
volatile-ttl:删除ttl最小的键(key需要设置过期时间) allkeys-lru:使用LRU算法删除键(所有key) allkeys-random:随机删除键(所有key) noeviction:不进行任何的操作,只返回错误,默认redis的算法 [root@redis01 ~]# redis-cli config get maxmemory-policy #查看内存清理算法 1) "maxmemory-policy" 2) "noeviction" #默认noeviction12.4 模拟超过内存
[root@redis01 ~]# for line in `seq -w 2000`;do redis-cli set key_${line} value_${line};done #测试会发现报错 (error) OOM command not allowed when used memory > ‘maxmemory‘.12.5 设置删除算法
#将删除算法设置为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_0011
"value_0011"
[root@redis01 ~]# redis-cli expire key_0011 3600
(integer) 1
[root@redis01 ~]# redis-cli ttl key_0011
(integer) -2
[root@redis01 ~]# redis-cli get key_0011
(nil)
说明:由上述测试可以发现volatile-lru算法当内存到了最大值以后,会优先删除有过期时间的key。
十三,Redis禁用屏蔽危险命令
13.1 redis禁用的命令
FLUSHALL和FLUSHDB会清除redis的数据,比较危险 KEYS在键过多的时候使用会阻塞业务请求
13.2 redis禁用危险命令配置代码如下(写入配置文件即可,此配置无法平滑更新)
#将配置加入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 "" #将命令改名成空13.3 登陆redis,运行禁止命令进行测试
#重启redis-server [root@redis01 ~]# redis-cli shutdown [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 24399/redis-server#测试被屏蔽的危险命令
[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> key *
(error) ERR unknown command `key`, with args beginning with: `*`,
十四,Redis主从服务器环境的搭建
在工作中redis主库不开启任何持久化,rdb和aof肯定是全关闭的,任何影响主库性能全都关闭。 持久化都是在从上做| 主机名 | IP | 用途 |
| redis01 | 192.168.200.158 | redis-master |
| redis02 | 192.168.200.181 | redis-slaveA |
| redis03 | 192.168.200.178 | redis-slaveB |