一、redis理论概述
1.1 redis简介
1.2 redis优点
1.3 redis与memcached区别
数据库 类型 过期策略 数据类型 持久化 主从复制 虚拟内存 rdis K-V 支持 五大数据类型 支持 支持 支持 memcached K-V 支持 单一数据类型 不支持 不支持 不支持
1.4 关系型数据库与非关系型数据库
二、安装部署redis
[ root@localhost ~ ] # cd / opt/
[ root@localhost opt] # systemctl stop firewalld. service
[ root@localhost opt] # setenforce 0
[ root@localhost opt] # systemctl disable firewalld. service
[ root@localhost opt] # ls
redis- 5.0 .7 . tar. gz rh
[ root@localhost opt] # tar zxvf redis- 5.0 .7 . tar. gz
[ root@localhost opt] # cd redis- 5.0 .7 /
[ root@localhost redis- 5.0 .7 ] # yum - y install gcc gcc- c++ make
[ root@localhost redis- 5.0 .7 ] # make
[ root@localhost redis- 5.0 .7 ] # make PREFIX= / usr/ local/ redis install 【编译并且编译安装目录为/ usr/ local/ redis】
【由于redis源码包中直接提供了Makefile文件,所以在解压完软件包后,不用再执行. /configure进行配置,可直接执行make与make install命令进行安装】
[ root@localhost redis- 5.0 .7 ] # cd utils/
[ root@localhost utils] # ls
build- static - symbols. tcl create- cluster hashtable lru redis_init_script. tpl speed- regression. tcl
cluster_fail_time. tcl generate- command- help. rb hyperloglog redis- copy. rb redis- sha1. rb whatisdoing. sh
corrupt_rdb. c graphs install_server. sh redis_init_script releasetools
[ root@localhost utils] # . /install_server. sh 【执行软件包提供的. /install_server. sh 脚本文件设置redis服务所需要的相关配置文件】
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 ] 【回车确认端口号6379 】
Selecting default : 6379
Please select the redis config file name [ / etc/ redis/ 6379. conf] 【回车确认配置文件目录】
Selected default - / etc/ redis/ 6379. conf
Please select the redis log file name [ / var/ log/ redis_6379. log] 【回车确认日志文件目录】
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
Selected config:
Port : 6379 【默认侦听端口为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!
【把redis的可执行程序文件放入路径环境变量的目录中便于系统识别】
[ root@localhost utils] # ln - s / usr/ local/ redis/ bin/ * / usr/ local/ bin/
【当install_server. sh脚本运行完毕,redis服务就已开启,默认监听端口为6379 】
[ root@localhost utils] # netstat - tanp | grep 6379 【查看tcp协议6379 端口是否打开】
tcp 0 0 127.0 .0 .1 : 6379 0.0 .0 .0 : * LISTEN 9796 / redis- server 1
2.1redis服务控制
[ root@localhost utils] # / etc/ init. d/ redis_6379 status 【查看redis服务状态】
Redis is running ( 9796 )
[ root@localhost utils] # / etc/ init. d/ redis_6379 stop 【停止redis服务】
Stopping . . .
Waiting for Redis to shutdown . . .
Redis stopped
[ root@localhost utils] # / etc/ init. d/ redis_6379 start 【启动redis服务】
Starting Redis server. . .
[ root@localhost utils] # / etc/ init. d/ redis_6379 restart 【重启redis服务】
Stopping . . .
Waiting for Redis to shutdown . . .
Redis stopped
Starting Redis server. . .
[ root@localhost utils] # / etc/ init. d/ redis_6379 status
Redis is running ( 48085 )
2.2 修改配置参数
[ root@localhost utils] # cd / etc/ redis/
[ root@localhost redis] # ls
6379. conf
[ root@localhost redis] # vim 6379. conf 【修改配置文件,70 行添加监听主机,其他都为默认配置选项】
70 bind 192.168 .131 .10 【70 行,添加监听的主机地址】
93 port 6379 【93 行,redis默认的监听端口(6379 )】
137 daemonize yes 【137 行,启用守护进程】
159 pidfile / var/ run/ redis_6379. pid 【159 行,指定PID文件】
167 loglevel notice 【167 行,日志级别】
172 logfile / var/ log/ redis_6379. log 【172 行,指定日志文件】
[ root@localhost redis] # / etc/ init. d/ redis_6379 restart
Stopping . . .
Redis stopped
Starting Redis server. . .
[ root@localhost redis] # netstat - tanp | grep 6379
tcp 0 0 192.168 .131 .10 : 6379 0.0 .0 .0 : * LISTEN 48182 / redis- server
tcp 0 0 127.0 .0 .1 : 6379 127.0 .0 .1 : 47538 TIME_WAIT -
2.3 redis常用命令工具
[ root@localhost init. d] # redis- benchmark 【用于检测redis在本机的运行效率】
[ root@localhost init. d] # redis- check- aof 【修复AOF持久化文件】
[ root@localhost init. d] # redis- check- rdb 【修复RDB持久化文件】
[ root@localhost init. d] # redis- server 【用于启动redis的工具】
[ root@localhost init. d] # redis- cli 【redis命令行工具】
[ root@localhost init. d] # redis- cli - h 192.168 .131 .10 - p 6379 【本地登录使用redis- cli】
192.168 .131 .10 : 6379 >
2.4redis-benchmark测试工具
【向IP地址为192.168 .131 .10 ,端口6379 的redis服务器发送100 个并发连接与1 万个请求,测试性能】
[ root@localhost init. d] # redis- benchmark - h 192.168 .131 .10 - p 6379 - c 100 - n 10000
【测试存取大小为100 字节的数据包的性能】
[ root@localhost init. d] # redis- benchmark - h 192.168 .131 .10 - p 6379 - q - d 100
【测试本机上redis服务在进行set与lpush操作时的性能】
[ root@localhost init. d] # redis- benchmark - t set, lpush - n 100000 - q
2.5 redis数据库常用命令
[ root@localhost ~ ] # redis- cli - h 192.168 .131 .10 - p 6379
192.168 .131 .10 : 6379 > set boss qz 【键:boss;值:qz】
OK
192.168 .131 .10 : 6379 > get boss 【获取boss键的值】
"qz"
192.168 .131 .10 : 6379 > set q1 10
OK
192.168 .131 .10 : 6379 > set q2 20
OK
192.168 .131 .10 : 6379 > set q3 30
OK
192.168 .131 .10 : 6379 > set z4 40
OK
192.168 .131 .10 : 6379 > set z5 50
OK
192.168 .131 .10 : 6379 > set z66 50
OK
192.168 .131 .10 : 6379 > set z6677 501
OK
192.168 .131 .10 : 6379 > keys * 【查看当前数据库中所有键】
192.168 .131 .10 : 6379 > keys *
1 ) "counter:__rand_int__"
2 ) "z66"
3 ) "z5"
4 ) "key:__rand_int__"
5 ) "boos"
6 ) "z4"
7 ) "mylist"
8 ) "q2"
9 ) "boss"
10 ) "q1"
11 ) "z6677"
12 ) "myset:__rand_int__"
13 ) "q3"
192.168 .131 .10 : 6379 > keys q* 【查看当前数据库中键名以q开头的键】
1 ) "q2"
2 ) "q1"
3 ) "q3"
192.168 .131 .10 : 6379 > keys z* 【查看当前数据库中键名以z开头且后面包含任意一位的键】
1 ) "z66"
2 ) "z5"
3 ) "z4"
4 ) "z6677"
192.168 .131 .10 : 6379 > keys z? ? 【查看当前数据库中键名以z开头且后面包含任意两位数的键】
1 ) "z66"
192.168 .131 .10 : 6379 > keys z? ? ? ? 【查看当前数据库中键名以z开头且后面包含任意四位数的键】
1 ) "z6677"
192.168 .131 .10 : 6379 > exists q 【判断q键是否存在】
( integer) 0 【返回值0 表示不存在】
192.168 .131 .10 : 6379 > exists q1
( integer) 1 【返回值1 表示存在】
192.168 .131 .10 : 6379 > keys *
1 ) "counter:__rand_int__"
2 ) "z66"
3 ) "z5"
4 ) "key:__rand_int__"
5 ) "boos"
6 ) "z4"
7 ) "mylist"
8 ) "q2"
9 ) "boss"
10 ) "q1"
11 ) "z6677"
12 ) "myset:__rand_int__"
13 ) "q3"
192.168 .131 .10 : 6379 > del boos 【删除boos键】
( integer) 1
192.168 .131 .10 : 6379 > get boos
( nil)
192.168 .131 .10 : 6379 > keys * 【查看所有键无boos键】
1 ) "counter:__rand_int__"
2 ) "z66"
3 ) "z5"
4 ) "key:__rand_int__"
5 ) "z4"
6 ) "mylist"
7 ) "q2"
8 ) "boss"
9 ) "q1"
10 ) "z6677"
11 ) "myset:__rand_int__"
12 ) "q3"
192.168 .131 .10 : 6379 > type z6677
string 【string:字符串】
192.168 .131 .10 : 6379 > type z1
none
192.168 .131 .10 : 6379 > type q1
string
192.168 .131 .10 : 6379 > keys q* 【查看所有q开头的键】
1 ) "q4"
2 ) "q2"
3 ) "q3"
192.168 .131 .10 : 6379 > get q4 【获取q4键的值】
"10"
192.168 .131 .10 : 6379 > rename q4 q1 【将q4键重命名为q1键】
OK
192.168 .131 .10 : 6379 > get q1 【查看q1键的值】
"10"
192.168 .131 .10 : 6379 > get q4
( nil)
192.168 .131 .10 : 6379 > keys q*
1 ) "q2"
2 ) "q1"
3 ) "q3"
192.168 .131 .10 : 6379 > keys z* 【查看所有以z开头的键】
1 ) "z66"
2 ) "z5"
3 ) "z4"
4 ) "z6677"
192.168 .131 .10 : 6379 > get z66 【获取z66键的值】
"50"
192.168 .131 .10 : 6379 > renamenx z66 z5 【将z66键重命名为z5】
( integer) 0 【但是z5键本来就存在,所以执行失败,返回0 】
192.168 .131 .10 : 6379 > keys z*
1 ) "z66"
2 ) "z5"
3 ) "z4"
4 ) "z6677"
192.168 .131 .10 : 6379 > get z66
"50"
192.168 .131 .10 : 6379 > renamenx z66 z1 【将z66键重命名为z1】
( integer) 1 【z1键不存在,所以返回1 】
192.168 .131 .10 : 6379 > keys z* 【查看所有z开头的键,发现z66键不存在,多了个z1键】
1 ) "z1"
2 ) "z5"
3 ) "z4"
4 ) "z6677"
192.168 .131 .10 : 6379 > get z1 【获取z1键的值就是之前z66键的值】
"50"
192.168 .131 .10 : 6379 > DBSIZE
( integer) 12
192.168 .131 .10 : 6379 > CONFIG SET requirepass 5514
OK
192.168 .131 .10 : 6379 > key *
( error) ERR unknown command `key`, with args beginning with: `* `,
192.168 .131 .10 : 6379 > config get requirepass
( error) NOAUTH Authentication required.
192.168 .131 .10 : 6379 > auth 5514
OK
192.168 .131 .10 : 6379 > config get requirepass
1 ) "requirepass"
2 ) "5514"
[ root@localhost ~ ] # / etc/ init. d/ redis_6379 restart
Stopping . . .
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
( error) NOAUTH Authentication required.
Waiting for Redis to shutdown . . .
Waiting for Redis to shutdown . . .
[ root@localhost ~ ] # redis- cli - h 192.168 .131 .10 - p 6379
192.168 .131 .10 : 6379 > auth 5514
OK
192.168 .131 .10 : 6379 > CONFIG SET requirepass ''
OK
[ root@localhost ~ ] # / etc/ init. d/ redis_6379 restart
Stopping . . .
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Waiting for Redis to shutdown . . .
Redis stopped
Starting Redis server. . .
2.6 redis多数据库常用命令
【使用redis- cli连接redis数据库后,默认使用的是0 号数据库】
[ root@localhost ~ ] # redis- cli - h 192.168 .131 .10 - p 6379
192.168 .131 .10 : 6379 > select 16 【切换至16 号数据库】
( error) ERR DB index is out of range
192.168 .131 .10 : 6379 > select 15 【切换至15 号数据库】
OK
192.168 .131 .10 : 6379 [ 5 ] > keys * 【查看15 号数据库无键值数据】
( empty list or set)
192.168 .131 .10 : 6379 [ 15 ] > set q1 100 【在15 号库创建键q1,值100 】
OK
192.168 .131 .10 : 6379 [ 15 ] > keys * 【查看15 号库里所有键】
1 ) "q1"
192.168 .131 .10 : 6379 [ 15 ] > get q1 【查看15 号库里的q1键值】
"100"
192.168 .131 .10 : 6379 [ 15 ] > select 10 【切换到10 号库】
OK
192.168 .131 .10 : 6379 [ 10 ] > keys * 【查看10 号库所有键】
( empty list or set)
192.168 .131 .10 : 6379 [ 10 ] > select 15
OK
192.168 .131 .10 : 6379 [ 15 ] > move q1 10 【将15 号库里的q1键移动到10 号库】
( integer) 1
192.168 .131 .10 : 6379 [ 15 ] > keys * 【查看15 号库,无键】
( empty list or set)
192.168 .131 .10 : 6379 [ 15 ] > select 10 【切换到10 号库】
OK
192.168 .131 .10 : 6379 [ 10 ] > keys * 【查看10 号库里所有键】
1 ) "q1"
192.168 .131 .10 : 6379 [ 10 ] > get q1 【查看10 号库里q1键的值】
"100"
192.168 .131 .10 : 6379 > select 9
OK
192.168 .131 .10 : 6379 [ 9 ] > set q1 100
OK
192.168 .131 .10 : 6379 [ 9 ] > keys *
1 ) "q1"
192.168 .131 .10 : 6379 [ 9 ] > select 10
OK
192.168 .131 .10 : 6379 [ 10 ] > keys *
1 ) "q1"
192.168 .131 .10 : 6379 [ 10 ] > flushdb 【清空当前数据库的数据】
OK
192.168 .131 .10 : 6379 [ 10 ] > keys *
( empty list or set)
192.168 .131 .10 : 6379 [ 10 ] > select 9 【因为只是情况了9 号库的数据,所以10 号库的数据还在】
OK
192.168 .131 .10 : 6379 [ 9 ] > keys *
1 ) "q1"
192.168 .131 .10 : 6379 [ 9 ] > flushall 【情况所有数据库的数据】
OK
192.168 .131 .10 : 6379 [ 9 ] > keys *
( empty list or set)
192.168 .131 .10 : 6379 [ 9 ] > select 0
OK
192.168 .131 .10 : 6379 > keys *
( empty list or set)
三、redis高可用
3.1 redis高可用概述
3.2 持久化的功能
3.3 持久化RDB和AOF区别
RDB AOF 对redis中的数据执行周期性的持久化。简而言之就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上。持续的用日志记录写操作,crash(崩溃)后利用日志恢复。 通过在指定的时间间隔内将内存中的数据集快照写入磁盘的实际操作过程是fork一个子进程,然后先将数据集写入临时文件,写入成功后,再替换之前的文件,并用二进制压缩存储 换了一个角度来实现持久化,也就是将redis执行过的所有写、删(查询操作不会)指令记录下来,在下次redis重新启动时只要把这些写指令从前到后再重复执行一遍,即可实现数据恢复。平时写操作的时候不会触发写,只有手动提交save命令或者shutdown关闭命令时才会触发备份操作
3.4 持久化RDB和AOF的优缺点
四、redis持久化
4.1 RDB
4.1.1 触发条件
【当满足219 行- 221 行的三个save条件的任意一个时,都会引起bgsave的调用】
[ root@localhost ~ ] # vim / etc/ redis/ 6379. conf
219 save 900 1 【当时间到900 秒时,如果redis数据发生了至少1 次变化,则执行bgsave】
220 save 300 10 【当时间到300 秒时,如果redis数据发生了至少10 次变化,则执行bgsave】
221 save 60 10000 【当时间到60 秒时,如果redis数据发生了至少10000 次变化,则执行bgsave】
242 rdbcompression yes 【是否开启RDB文件压缩】
254 dbfilename dump. rdb 【指定RDB文件名】
264 dir / var/ lib/ redis/ 6379 【指定RDB文件和AOF文件所在目录】
4.1.2 执行流程
4.1.3 启动时加载
4.2 AOF
4.2.1 开启AOF
[ root@localhost ~ ] # vim / etc/ redis/ 6379. conf
700 appendonly yes 【改为yes, 开启AOF】
704 appendfilename "appendonly.aof" 【指定AOF文件名称】
796 aof- load- truncated yes 【是否忽略最后一条可能存在问题的指令】
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- aof- load- truncated yes-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
aof- load- truncated yes 指的的是当redis在恢复时,会忽略最后一条可能存在问题的指令。默认yes,即在AOF写入时,可能存在指令写错
的问题(突然断电,写了一半),这种情况下,yes则会log并继续,no则会直接恢复失败
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
[ root@localhost ~ ] # / etc/ init. d/ redis_6379 restart 【如有密码需要先取消密码再进行重启】
[ root@localhost ~ ] # ls / var/ lib/ redis/ 6379 /
appendonly. aof dump. rdb
4.2.2 执行流程(命令追加、文件写入、文件重写)
[ root@localhost ~ ] # vim / etc/ redis/ 6379. conf
773 auto- aof- rewrite- percentage 100
【当前AOF文件大小(aof_current_size)是上次日志重写时AOF文件大小(aof_base_size)两倍时,发生bgrewriteaof操作】
774 auto- aof- rewrite- min- size 64 mb
【当前AOF文件执行bgrewriteaof命令的最小值,避免刚开始启动redis时由于文件较小导致频繁的进行bgrewriteaof操作】
4.2.3 文件重写流程
①Redis父进程首先判断当前是否存在正在执行bgsave/bgrewriteaof的子进程,如果存在则bgrewriteaof命令直接返回,如果存在bgsave命令则等bgsave执行完成后再执行 ②父进程执行fork操作创建子进程(这个过程中父进程是阻塞的) ③父进程fork后,bgrewriteaof命令返回”Background append only file rewrite started”信息并不再阻塞父进程, 并可以响应其他命令。Redis的所有写命令依然写入AOF缓冲区,并根据appendfsync策略同步到硬盘,保证原有AOF机制的正确
由于fork操作使用写时复制技术,子进程只能共享fork操作时的内存数据。但是因为父进程依然在响应命令,所以redis使用AOF重写缓冲区(aof_rewrite_buf)保存这部分数据,防止新AOF文件生成期间丢失这部分数据。也就是说在bgrewriteaof执行期间,redis的写命令同时追加到aof_buf和aof_rewrite_buf两缓冲区 ④子进程根据内存快照,按照命令合并规则写入到新的AOF文件
子进程写完新的AOF文件后,向父进程发信号,父进程更新统计信息,可以通过info persistence查看 父进程把AOF重写缓冲区的数据写入到新的AOF文件,这样就保证了新AOF文件所保存的数据库状态和服务器当前状态一致 使用新的AOF文件替换老文件,完成AOF重写
4.2.4 AOF缓存区同步文件策略的方式(三种)
4.2.5 启动时加载
五、redis性能管理
5.1 查redis内存使用
[ root@localhost ~ ] # redis- cli - h 192.168 .131 .10 - p 6379
192.168 .131 .10 : 6379 > info memory
5.2 内存碎片率
5.3 内存使用率
5.4 内回收key
[ root@localhost ~ ] # vim / etc/ redis/ 6379. conf
598 maxmemory- policy noeviction 【取消注释】
参数 说明 volatile-lru 使用lru算法从已设置过期时间的数据集合中淘汰数据 volatile-ttl 从已设置过期时间的数据集合中挑选即将过期的数据淘汰 volatile-random 从已设置过期时间的数据集合中随机挑选数据淘汰 allkeys-lru 使用lru算法从所有数据集合中淘汰数据 allkeys-random 从数据集合中任意选择数据淘汰 noenviction 禁止淘汰数据
六、总结
6.1 reids
6.2 关系与非关系型数据库