大点干!早点散----------Redis从入门到精通!!!

时间:2022-07-24
本文章向大家介绍大点干!早点散----------Redis从入门到精通!!!,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、redis简介

1、概述

redis(REmote DIctionary Server)是一个由Salvatore Sanfilippo写key-value存储系统,它由C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value类型的数据库,并提供多种语言的API。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步,redis在3.0版本推出集群模式。

2、特点、优势

k、v键值存储以及数据结构存储(如列表、字典) 所有数据(包括数据的存储)操作均在内存中完成 单线程服务(这意味着会有较多的阻塞情况),采用epoll模型进行请求响应,对比nginx 支持主从复制模式,更提供高可用主从复制模式(哨兵) 去中心化分布式集群 丰富的编程接口支持,如Python、Golang、Java、php、Ruby、Lua、Node.js 功能丰富,除了支持多种数据结构之外,还支持事务、发布/订阅、消息队列等功能 支持数据持久化(AOF、RDB)

3、对比memcache

memcache是一个分布式的内存对象缓存系统,并不提供持久存储功能,而redis拥有持久化功能 memcache数据存储基于LRU(简单说:最近、最少使用key会被剔除),而redis则可以永久保存(服务一直运行情况下) memcache是多线程的(这是memcache优势之一),也就意味着阻塞情况少,而redis是单线程的,阻塞情况相对较多 两者性能上相差不大 memcache只支持简单的k、v数据存储,而redis支持多种数据格式存储。 memcache是多线程、非阻塞IO复用网络模型,而redis是单线程IO复用模型

4、Redis相对MySQL关系型数据库优缺点

Redis主要用来做缓存,它有持久化,但也只是为了缓存的可靠性。 Redis是一种内存数据库,最大优点在于数据全放在内存,速度快,效率高。尤其是在某些特定场合,比如热点数据量非常大,而数据在内存和磁盘之间切换代价比较高的场景下,适合应用Redis。但缺点是数据不能超过内存大小。

传统关系型数据库在于它对数据的一致性保障,它的数据模型范式是遵循严格事物规则的结构化数据,由于其数据的高度抽象化,它调度到内存的数据一般场合下不会占用很大的内存空间。

Redis和MySQL各自有不同的业务场景,谁都无法取代谁。

二、源码安装redis

1、安装环境组件编译器,编译安装redis

[root@redis ~]# yum install gcc gcc-c++ make -y
[root@redis redis]# tar zxvf redis-5.0.7.tar.gz -C /opt	'//redis源码包可以直接到官网下载'
[root@redis redis]# cd /opt/redis-5.0.7/
[root@redis redis-5.0.7]# make	'//直接进行make'
[root@redis redis-5.0.7]#  make PREFIX=/usr/local/redis/ install	'//指定redis目录并安装'
[root@redis redis-5.0.7]# cd /usr/local/redis/
[root@redis redis]# ls
bin
[root@redis redis]# cd bin/
[root@redis bin]# ls
redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis-sentinel  redis-server	'//redis-cli是连接终端'

redis-server     #Redis服务器和Sentinel服务器,启动时候可使用–sentinel指定为哨兵 redis-cli      #Redis命令行客户端 redis-benchmark  #Redis性能测试工具 redis-check-aof #AOF文件修复工具 redis-check-dump #RDB文件检测工具 redis-sentinel #Sentinel服务器,4.0版本已经做了软链接到redis-server

2、执行redis配置文件脚本,并进行配置

[root@redis bin]# cd /opt/redis-5.0.7/utils/	'//回到redis源码包内的工具包'
[root@redis utils]# ./install_server.sh 	'//执行脚本进行配置'
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 	'//选择redis默认接口,直接回车'
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] 	'//选择redis默认配置文件名称,直接回车'
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 	'//选择默认redis日志文件名称,直接回车'
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] 	'//选择默认接口的默认数据文件,直接回车'
Selected default - /var/lib/redis/6379
Please select the redis executable path [] /usr/local/redis/bin/redis-server	'//选择redis可执行文件路径,需要手动输入此路径:/usr/local/redis/bin/redis-server'
Selected config:	'//选择的配置清单展示'
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/redis/bin/redis-server
Cli Executable : /usr/local/redis/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.	'//直接回车完成配置'
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!

3、配置优化启动项

[root@redis utils]# ln -s /usr/local/redis/bin/* /usr/local/bin	'//将redis命令创建软连接,便于系统识别'
[root@redis utils]# netstat -ntap |grep 6379
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      26085/redis-server  
[root@redis utils]# /etc/init.d/redis_6379 stop	'//先关闭redis服务'
Stopping ...
Redis stopped
[root@redis utils]# /etc/init.d/redis_6379 start	'//开启redis服务'
Starting Redis server...
[root@redis utils]# netstat -ntap |grep 6379	'//再次检查redis开启情况'
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      36566/redis-server  
tcp        0      0 127.0.0.1:6379          127.0.0.1:60648         TIME_WAIT   -  

4、设置监听端口,启动服务

[root@redis utils]# vim /etc/redis/6379.conf 	'//修改配置文件'
bind 127.0.0.1 192.168.110.132	'//添加监听端口'
[root@redis utils]# /etc/init.d/redis_6379 restart	'//重启redis服务'
Stopping ...
Redis stopped
Starting Redis server...
[root@redis utils]# redis-cli -h 192.168.110.132 -p 6379	'//成功登陆'
192.168.110.132:6379> exit	'//退出'
[root@redis utils]# 

三、redis配置参数介绍

1、redis主配置文件的介绍

logfile          '日志文件位置及文件名称'


bind 0.0.0.0        '监听地址,可以有多个 如bind 0.0.0.0 127.0.0.1'


daemonize yes     'yes启动守护进程运行,即后台运行,no表示不启用'


pidfile /var/run/redis.pid   '当redis在后台运行的时候,Redis默认会把pid文件在在/var/run/redis.pid,也可以配置到其他地方'
# 当运行多个redis服务时,需要指定不同的pid文件和端口

port 6379         '指定redis运行的端口,默认是6379'

unixsocket    'sock文件位置'


unixsocketperm    'sock文件权限'


timeout 0   '# 设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接, 0是关闭此设置'


loglevel debug  '# 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose'


logfile ""    '# 日志文件配置,默认值为stdout,标准输出,若后台模式会输出到/dev/null'


syslog-enabled    '# 是否以syslog方式记录日志,yes开启no禁用,与该配置相关配置syslog-ident 和syslog-facility local0 分别是指明syslog的ident和facility'

databases 16    '#配置可用的数据库个数,默认值为16,默认数据库为0,数据库范围在0-(database-1)之间'


always-show-logo yes '#4.0以后新增配置   #是否配置日志显示redis徽标,yes显示no不显示'

四、redis数据库简单的命令操作

redis是key-value的数据结构,每条数据都是⼀个键值对 键的类型是字符串 值的类型分为五种: (1)字符串string (2)哈希hash (3)列表list (4)集合set (5)有序集合zset

1、string类型

字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度是512M。

(1)设置键值 SET 赋值 GET 取值

192.168.110.132:6379> set key value
OK
192.168.110.132:6379> get key
"value"

(2) INCR 递增数字

仅仅对数字类型的键有用,相当于Java的i++运算, 用法: incr key

192.168.110.132:6379> set s 1
OK
192.168.110.132:6379> incr s
(integer) 2
192.168.110.132:6379> incr s
(integer) 3
192.168.110.132:6379> incr s
(integer) 4

(3)incrby 增加指定的数字

仅仅对数字类型的键有用,相当于Java的i+=3, 用法:INCRBY key increment,意思是key自增increment,increment可以为负数,表示减少。

192.168.110.132:6379> incrby s 3
(integer) 7
192.168.110.132:6379> incrby s 3
(integer) 10
192.168.110.132:6379> 

(4)decr递减数字

仅仅对数字类型的键有用,相当于Java的i–,用法:DECR key

192.168.110.132:6379> decr s
(integer) 9
192.168.110.132:6379> decr s
(integer) 8
192.168.110.132:6379> decr s
(integer) 7
192.168.110.132:6379> 

(5)DECRBY 减少指定的数字

仅仅对数字类型的键有用,相当于Java的i-=3, 用法:DECRBY key decrement,意思是key自减decrement,decrement可以为正数,表示增加。

192.168.110.132:6379> decrby s 2
(integer) 5
192.168.110.132:6379> decrby s 2
(integer) 3
192.168.110.132:6379> decrby s -2
(integer) 5
192.168.110.132:6379> decrby s -2
(integer) 7
192.168.110.132:6379> 

(6)incrbyfloat 增加指定浮点数

仅仅对数字类型的键有用,用法:INCRBYFLOAT key increment

192.168.110.132:6379> incrbyfloat s 1.1
"8.1"
192.168.110.132:6379> incrbyfloat s 1.1
"9.2"
192.168.110.132:6379> incrbyfloat s -1.1
"8.1"
192.168.110.132:6379> incrbyfloat s -1.1
"7"
192.168.110.132:6379> 

(7)APPEND 向尾部追加值

相当于Java中的”hello”.append(“ world”),用法:APPEND key value

192.168.110.132:6379> append s shang
(integer) 6
192.168.110.132:6379> get s
"7shang"
192.168.110.132:6379> 

(8)STRLEN 获取字符串长度

用法:STRLEN key

192.168.110.132:6379> strlen s
(integer) 6

MSET 同时设置多个key的值,用法:MSET key1 value1 [key2 value2 …] MGET 同时获取多个key的值,用法:MGET key1 [key2 …]

192.168.110.132:6379> mset qq 11 [ww 22]
OK
192.168.110.132:6379> mget qq [ww]
1) "11"
2) (nil)

2、hash类型(对象存储)

⽤于存储对象,对象的结构为属性、值,值的类型为string

(1)设置单个属性

hset key field value

192.168.110.132:6379> hset person name koby 
(integer) 1
192.168.110.132:6379> hset person age 21
(integer) 1

192.168.110.132:6379> hget person name
"koby"

(2)设置多个属性

hmset key field1 value1 field2 value2

192.168.110.132:6379> hmset myhash name kobe age 39
OK
192.168.110.132:6379> mhget myhash name age
(error) ERR unknown command `mhget`, with args beginning with: `myhash`, `name`, `age`, 
192.168.110.132:6379> hmget myhash name age
1) "kobe"
2) "39"

(3)获取指定键所有的属性

hkeys key

192.168.110.132:6379> hkeys person
1) "name"
2) "age"

获取所有属性的值 hvals key

192.168.110.132:6379> hvals person
1) "koby"
2) "21"

(4)删除整个hash键及值

使⽤del命令

192.168.110.132:6379> hdel person name age
(integer) 2
192.168.110.132:6379> hkeys person
(empty list or set)
192.168.110.132:6379>

删除属性,属性对应的值会被⼀起删除 hdel key field1 field2

3、list类型

列表的元素类型为string,按照插⼊顺序排序 在左侧插⼊数据 lpush key value1 value2 在右侧插⼊数据 rpush key value1 value2 在指定元素的前或后插⼊新元素 linsert key before或after 现有元素 新元素 获取元素 lrange key start stop

192.168.110.132:6379> lpush sql redis 
(integer) 1
192.168.110.132:6379> lpush sql mysql
(integer) 2
192.168.110.132:6379> lrange sql 0 10
1) "mysql"
2) "redis"

start、stop为元素的下标索引 索引从左侧开始,第⼀个元素为0 索引可以是负数,表示从尾部开始计数,如-1表示最后⼀个元素

设置指定索引位置的元素值 lset key index value 索引从左侧开始,第⼀个元素为0 索引可以是负数,表示尾部开始计数,如-1表示最后⼀个元素

删除 lrem key count value 列表中前count次出现的值为value的元素移除 count > 0: 从头往尾移除 count < 0: 从尾往头移除 count = 0: 移除所有

4、set类型

⽆序集合 元素为string类型 元素具有唯⼀性,不重复 说明:对于集合没有修改操作

添加元素 sadd key member1 member2 返回所有的元素 smembers key 删除指定元素 srem key

5、zset类型

(1)类型

sorted set,有序集合 元素为string类型 元素具有唯⼀性,不重复 每个元素都会关联⼀个double类型的score,表示权重,通过权重将元素从⼩到⼤排序 说明:没有修改操作

添加 zadd key score1 member1 score2 member2

(2)元素介绍

获取 zrange key start stop 返回指定范围内的元素 start、stop为元素的下标索引 索引从左侧开始,第⼀个元素为0 索引可以是负数,表示从尾部开始计数,如-1表示最后⼀个元素

返回score值在min和max之间的成员 zrangebyscore key min max 返回成员member的score值 zscore key member 删除指定元素 zrem key member1 member2 删除权重在指定范围的元素 zremrangebyscore key min max

(3)常用命令介绍

192.168.110.132:6379> zrange zset01 0 1
1) "v1"
2) "v2"

192.168.110.132:6379> zrange zset01 -1 1
1) "v2"
192.168.110.132:6379> zrange zset01 -1 
(error) ERR wrong number of arguments for 'zrange' command
192.168.110.132:6379> zrange zset01 -1 1
1) "v2"
192.168.110.132:6379> zrange zset01 0 -1 withscores
1) "v1"
2) "60"
3) "v2"
4) "70"

Zadd——添加元素 Zrem——删除元素 Zrange——返回元素 Zrange withscores——根据score范围,返回元素 Zrangebyscore——根据score范围,返回元素,不包含 Zrangebyscore limit——根据score范围,截取,返回元素 Zcard——统计元素个数 Zcount——根据score范围,统计元素个数 Zrank——根据元素,获取索引index Zscore——根据元素,获取score值 Zrevrange——逆序,获取元素 Zrevrangebyscore——逆序,根据score范围,获取元素

6、移动键值对到其他的库中(一共16个库)

[root@redis utils]# redis-cli -h 192.168.79.133 -p 6379	'//连接数据库'
192.168.79.133:6379> keys *	'//默认进入第一个库0'
1) "key:__rand_int__"
2) "myset:__rand_int__"
3) "counter:__rand_int__"
4) "mylist"
5) "uuu"
192.168.79.133:6379> select 11	'//进入第12个库'
OK
192.168.79.133:6379[11]> keys *	'//查看所有键'
(empty list or set)
192.168.79.133:6379[11]> select 0	'//返回第一个库'
OK
192.168.79.133:6379> move uuu 11	'//将uuu键值对移动到第12个库'
(integer) 1
192.168.79.133:6379> select 11	'//进入第12个库'
OK
192.168.79.133:6379[11]> keys *	'//查看所有键'
1) "uuu"
192.168.79.133:6379[11]> get uuu	'//查看键值'
"ab"
192.168.79.133:6379[11]> flushdb	'//清空库'
OK
192.168.79.133:6379[11]> keys *
(empty list or set)
192.168.79.133:6379[11]> exit	'//退出'

7、Redis性能查询

'//查看Redis内存使用'
[root@redis 6379]# /usr/local/redis/bin/redis-cli 
127.0.0.1:6379> INFO memory
...省略内容

五、redis压测

[root@redis utils]# redis-benchmark -h 192.168.110.132 -p 6379 -c 100 -n 100000	'//压测ip地址192.168.79.133,端口为6379,并发量100,请求量100000个'
...省略内容
'//截取部分典型的结果展示'
====== SET ======	'//写入速度'
  100000 requests completed in 1.32 seconds	'//耗费1.32秒'
  100 parallel clients
  3 bytes payload
  keep alive: 1
====== GET ======	'//读取速度'
  100000 requests completed in 1.02 seconds	'//耗费1.02秒'
  100 parallel clients
  3 bytes payload
  keep alive: 1
...省略内容
'//压测结果想要标准,需要多压测几次,取平均值即可'
[root@redis utils]# redis-benchmark -h 192.168.79.133 -p 6379 -q -d 100	'//压测IP地址为192.168.79.133,端口为6379,-q:强制退出redis,-d:指定字节数量'
'//以字节形式指定set/get值的数据大小,同样仅展示部分结果'
    ...省略内容
SET: 53248.14 requests per second
GET: 46253.47 requests per second
...省略内容

六、Redis服务优化

1、Redis持久化的作用

Redis所有的数据都保存在内存中,对数据的更新将异步地保存在磁盘上

Redis持久化与高可能有很大关系。

2、Redis持久化的意义

在于数据备份和故障恢复。持久化主要是做灾难恢复,数据恢复

部署一个redis作为cache缓存,或保存一些较为重要的数据

如果没有持久化,redis遇到灾难性故障时,由于redis数据存储在内存中,就会丢失所有的数据

如果通过持久化将数据搞一份儿在磁盘上去,然后定期比如说同步和备份到一些云存储服务上去,就可以保证数据不丢失全部,还是可以恢复一部分数据回来的。

3、Redis持久化的重要性-缓存雪崩

如redis不可用了,要做的事是让redis尽快变得可用,重启redis,尽快让它对外提供服务,

如果没做数据备份,这时redis启动了也不可用,因为数据都没了。

有可能大量的请求过来,缓存全部无法命中,在redis里找不到数据,这时缓存雪崩问题,所有请求,没有在redis命中,就会去mysql数据库这种数据源头中去找,一下子mysql承接高并发,然后就挂了。

mysql挂掉,数据也就无法恢复到redis里面去。redis的数据从mysql来。。。

如果把redis的持久化做好,备份和恢复方案做到企业级的程度,即使redis故障了,也可通过备份数据,快速恢复,一旦恢复立即对外提供服务。

4、持久化的方式:

快照(先把数据拷贝出来,做个备份):Mysql Dump 和 Redis RDB 日志(某时某点的日志记录):MySQL Binlog和Hbase HLog和Redis AOF PDB(快照)和AOF(日志)

RDB和AOF两种持久化机制的工作原理:

(1)RDB工作原理

(2)AOF工作原理

AOF重写机制 AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多 当AOF文件的大小超过所设定的阀值时,Redis就会对AOF文件的内容压缩 原理 Redis会fork出一条新进程,读取内存中的数据(并没有读取旧文件),并重新写到一个临时文件中,最后替换旧的aof文件 重写配置

[root@redis 6379]# vim /etc/redis/6379.conf 
no-appendfsync-on-rewrite no	'//在日志进行BGREWRITEAOF时, 如果设置为yes表示新写操作不进行同步fsync,只暂存在缓冲区里,避免造成磁盘I0操作冲突,等重写完成后在写入。redis中默认为no'
auto-aof-rewrite-percentage 100	'//当前AOF文件大小是上次日志重写时AOF文件大小两倍时,发生BGREWRITEAOF操作'
auto-aof-rewrite-min-size 64mb	'//当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF.当AOF文件到达64M的时候,发生BGREWRITEAOF操作'

(3)两者的优缺点

RDB优点与AOF的对比 (1)RDB会生成多个数据文件,每个数据文件都代表了某一个时刻中redis的数据,这种多个数据文件的方式,非常适合做冷备,可以将这种完整的数据文件发送到一些远程的安全存储上去,比如说Amazon的S3云服务上去,在国内可以是阿里云的ODPS分布式存储上,以预定好的备份策略来定期备份redis中的数据 RDB也可以做冷备,生产多个文件,每个文件都代表某一时刻的完整数据快照 AOF也可以做冷备,只有一个文件,但是可以使用脚本或corntab每隔一段时间拷贝一份 RDB做冷备的优势:利用Redis去控制固定时长去生成快照文件,比较方便;AOF需要自己去做,但是在数据损坏的情况下,AOF比RDB数据恢复的时间快

(2)RDB对redis对外提供的读写服务,影响非常小,可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可 RDB每次写都是自己写入内存,只是在一定时候,才会将数据写入磁盘中 AOF每次都要写入文件,虽然可以快速OS cache,但是还是会产生一定的开销,速度会比RDB略慢

(3)相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复redis进程,更加快速 RDB:就是一份数据文件,恢复的时候直接加载到内存中 AOF:存放的指令日志,做数据恢复时,通过将日志中的指令回放和执行来恢复内存中的数据

缺点 1)如果想要在redis故障时,尽可能少的丢失数据,那么RDB没有AOF好。一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦redis进程宕机,那么会丢失最近5分钟的数据 这个问题也是RDB最大的缺点,就是不适合做第一优先的恢复方案,如果依赖RDB做第一优先恢复方案,会导致数据丢失的比较多 (2)RDB每次在fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒 一般不要让RDB间隔时间太长,否则每次生成的RDB文件太大,对Redis本身的性能会有影响

AOF 的优点 (1)AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据 如果你要保证一条数据都不丢失,也是可以的,将AOF的fsync设置为没写入一条数据就fsync一次,但是Redis的性能将会大幅度下降 (2)AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复

(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。因为在rewrite log的时候,会对其中的指导进行压缩,创建出一份需要恢复数据的最小日志出来。再创建新日志文件的时候,老的日志文件还是照常写入。当新的merge后的日志文件ready的时候,再交换新老日志文件即可。

(4)AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据 复制代码 缺点:

(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大 (2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的 (3)以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。所以说,类似AOF这种较为复杂的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份完整的数据快照文件的方式,更加脆弱一些,容易有bug。不过AOF就是为了避免rewrite过程导致的bug,因此每次rewrite并不是基于旧的指令日志进行merge的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。

5、、RDB和AOF到底该如何选择

(1)不要仅仅使用RDB,因为那样会导致你丢失很多数据 (2)也不要仅仅使用AOF,因为那样有两个问题,第一,你通过AOF做冷备,没有RDB做冷备,来的恢复速度更快; 第二,RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug (3)综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择; 用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复

6、配置AOF持久化

[root@redis 6379]# vim /etc/redis/6379.conf 
appendonly no	'//修改为yes即可开启AOF持久化'
appendfilename "appendonly.aof"	'//AOF文件名称'
# appendfsync always	'//always:同步持久化,每次发生数据变化会立刻写入磁盘这样的话使redis性能大幅度下降'
appendfsync everysec	'//everysec:默认推荐,每秒异步记录次(默认值)'
# appendfsync no	'//no:不同步,交给操作系统决定如何同步'
'//取消注释的时候注意前方空格,一定要删掉'
aof-load-truncated yes	'//忽略最后一条可能存在问题的指令'

7、什么是内存碎片率?

解释: 相当于一个个的格子 最多可存储4k 第一个存了1k 我要在存4k 那么就要开始新开了一个格子 那么第一个格子的剩余的空间就浪费了

操系统分配的内存值used_ memory rss除以redis使用的内存值 used _memory计算得出

内存碎片是由操作系统低效的分配/回收物理内存导致的 不连续的物理内存分配 跟踪内存碎片率对理解redis实例的资源性能是非常重要的 内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低 内存碎片率超过1.5,说明redis消耗了实际需要物理内存的150%,其中50%是内存碎片率 就要进行清除优化了 内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换

(1)回收key

保证合理分配redis有限的内存资源 当内存使用达到设置的最大阀值时,需要选择一种key的回收策略 默认情况下回收策略是禁止删除

redis.conf配置文件中修改maxmemory-policy属性值
volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据
volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰(建议使用)
volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰

allkeys-lru:使用LRU算法从所有数据集合中淘汰数据
allkeys-random:从数据集合中任意选择数据淘汰
no-enviction:禁止淘汰数据