- Redis简介
- redis服务器是单进程模型,也就是一台服务器上可以同时启动多个redis进程,实际处理速度完全依靠主进程的执行效率。服务器上运行的进程过少,服务器处理能力无法得到体现,运行进程过多,redis并发处理能力提高,但是服务器Cpu会有很大压力,所以在实际生产环境中,一般根据需求决定开启多少redis进程。
- 由于redis的数据存储在缓存,这个特性给redis带来了极高的数据读写速度。虽然其数据存储在缓存,但redis的数据同时也可以持久化到磁盘中,所以也不必担心数据的丢失。存储的数据类型也是多种多样,支持string、list、set、hash、ordered set等结构。
- redis基于内存运行,缓存是其最常应用的场景之一。常见的应用场景包括:获取最新N个数据的操作、排行榜类应用、计数器应用、存储关系、实时分析系统、日志系统等。
- redis在事务性上会稍显弱势,其价值点在于高扩展性和大数据量方面。这限制了放入其缓存中数据的形态,其中比较适合的包括即时性数据、数据一致性要求不高数据、访问量大且更新频率不高数据等。
- 编译安装Redis数据库部署
- 提前安装自动化构建和连接、编译redis安装包的编译器、工具,一般这些工具在系统中自带;但某些服务器为最小化安装,需要对这些工具进行安装
[root@localhost ~]# yum install -y gcc gcc-c++ make
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
epel/x86_64/metalink | 13 kB 00:00
* base: mirrors.aliyun.com
* epel: fedora.cs.nctu.edu.tw
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
软件包 gcc-4.8.5-44.el7.x86_64 已安装并且是最新版本
软件包 gcc-c++-4.8.5-44.el7.x86_64 已安装并且是最新版本
软件包 1:make-3.82-24.el7.x86_64 已安装并且是最新版本
无须任何处理
- 解压源码包,并进行编译
解压过程非常漫长,在解压的时候都会指定到/opt/目录
[root@localhost ~]# tar zxvf redis-7.2.4.tar.gz -C /opt/
redis-7.2.4/
redis-7.2.4/.codespell/
redis-7.2.4/.codespell/.codespellrc
redis-7.2.4/.codespell/requirements.txt
redis-7.2.4/.codespell/wordlist.txt
redis-7.2.4/.gitattributes
redis-7.2.4/.github/
redis-7.2.4/.github/ISSUE_TEMPLATE/
redis-7.2.4/.github/ISSUE_TEMPLATE/bug_report.md
...........
make根据源代码之间的依赖关系,自动编译并生成目标文件、可执行文件或库文件
[root@localhost ~]# cd /opt
[root@localhost opt]# ls
redis-7.2.4 rh
[root@localhost opt]# cd redis-7.2.4/
[root@localhost redis-7.2.4]# make
cd src && make all
which: no python3 in (/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin)
make[1]: 进入目录“/opt/redis-7.2.4/src”
.............
在执行make后,再执行make PREFIX=/usr/local/redis install,可以指定安装路径,在这个实例中就安装在了/usr/local/redis目录下
[root@localhost redis-7.2.4]# make PREFIX=/usr/local/redis install
cd src && make install
which: no python3 in (/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin)
make[1]: 进入目录“/opt/redis-7.2.4/src”
CC Makefile.dep
make[1]: 离开目录“/opt/redis-7.2.4/src”
which: no python3 in (/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin)
make[1]: 进入目录“/opt/redis-7.2.4/src”
Hint: It's a good idea to run 'make test' ;)
INSTALL redis-server
INSTALL redis-benchmark
INSTALL redis-cli
make[1]: 离开目录“/opt/redis-7.2.4/src”
由于redis服务里面存在一个长久的漏洞,为了安全性,对他的执行用户、命令等进行优化。
[root@localhost redis-7.2.4]# cd /usr/local/redis/
[root@localhost redis]# ls
bin
[root@localhost redis]# mkdir conf log data
[root@localhost redis]# ls
bin conf data log
[root@localhost redis]# cp /opt/redis-7.2.4/redis.conf /usr/local/redis/conf/
[root@localhost redis]# useradd -r redis
[root@localhost redis]# chown -R redis.redis /usr/local/redis/
[root@localhost redis]# ln -s /usr/local/redis/bin/* /usr/local/bin/ #保证所有用户都可以调用命令,另一种实现方式是修改/etc/profile文件,但请注意修改此文件后需要重启服务器,登录用户才能读取配置,而在生产环境不允许重启的情况下,使用source /etc/profile或者export PATH=$PATH:/usr/local/redis/bin/来连接配置。
附言:yum安装:先装一个epel-release源,再直接yum安装redis就可以,但是安装版本较低,一般是3.2版,在生产环境下需要根据需求进行相应版本的安装。
- 配置文件
1、一个配置文件可以监听一个端口,开启一个进程,所以我们对配置文件进行复制备份留存,在后续其他进程启用中,方便使用创建
[root@localhost ~]# cd /usr/local/redis/conf/
[root@localhost conf]# ls
redis.conf
[root@localhost conf]# cp redis.conf 6379.conf
[root@localhost conf]# mv redis.conf redis.conf.bak
[root@localhost conf]# cat 6379.conf |grep -v "^$"|grep -v '^#'
bind 127.0.0.1 -::1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
locale-collate ""
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-diskless-sync-max-replicas 0
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
appendonly no
appendfilename "appendonly.aof"
appenddirname "appendonlydir"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
aof-timestamp-enabled no
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-listpack-entries 512
hash-max-listpack-value 64
list-max-listpack-size -2
list-compress-depth 0
set-max-intset-entries 512
set-max-listpack-entries 128
set-max-listpack-value 64
zset-max-listpack-entries 128
zset-max-listpack-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
2、配置文件中,各参数说明
(1)以下参数说明了redis登录需要调用./redis-server命令,后面跟的是默认配置文件路径,我们对此进行了修改,所以后续登录时我们需要指定配置文件,指定不同的配置文件可以启动不同的redis进程,这就是redis单进程模型启动多进程的方法
(2)对存储单位进制进行了说明,使用过程中注意事项
(3)当有其他配置的时候可以通过include引入
(4)模块加载,当有其他模块的时候,可以通过loadmodule引入
(5)监听地址,默认是监听回环地址,为了外地地址访问redis,我们需要修改为监听本机地址
(6)保护设置,选择关闭,关闭后可以无密码登录,生产环境为了安全最好打开
(7)监听端口号,默认启动redis是6379端口,如果开启另外的redis进程,配置文件中需要改变
(8)启动进程后是redis进程默认是前台运行,我们修改为作为守护进程运行,这样他启动后直接将自己放入后台继续运行,即使关闭启动他的终端
(9)此处指定了启动进程后存放pid的目录,为了后期维护方便,我们统一存放到redis安装的目录下,没有run目录请新建一个,保证有执行权限
(10)运行日志文件,默认此文件是作为标准输出,而由于我们将他修改为守护后台进程,同时将被丢弃;所以我们指定他的存放文件
(11)默认存在16个数据库,编号从0到15
(12)存储数据的位置,默认的这个位置在配置文件,我们设置在存储数据的位置
附言:配置文件修改好以后,如果需要开启多个进程,则直接复制一份配置文件,修改里面监听的端口号
[root@localhost conf]# cp 6379.conf 6380.conf
[root@localhost conf]# sed -i s/6379/6380/ 6380.conf
3、启动运行服务,启动后运行redis-cli与服务器进行交互、连接,操作其中的数据,由于更改了监听地址,需要-h指定网址;如果还有其他端口服务,需要-p指定;如果设置了密码,需要-a指定输入密码;默认连接的是0号数据库,可以使用select切换
[root@localhost conf]# redis-server /usr/local/redis/conf/6379.conf
[root@localhost conf]# netstat -naptu |grep redis
tcp 0 0 192.168.201.6:6379 0.0.0.0:* LISTEN 5113/redis-server 1
[root@localhost conf]# redis-cli -h 192.168.201.6
192.168.201.6:6379>
四、redis服务器基本操作、常用命令
- 字符串操作
set:设置一个键和他的值,如果此键已存在,则覆盖旧值。
192.168.201.6:6379> set name lisi
OK
get:获取指定键的值
192.168.201.6:6379> get name
"lisi"
(2)哈希操作
hset:设置哈希表字段的值。如果哈希表不存在,一个新的哈希表被创建并进行hset操作
192.168.201.6:6379> hset age 1 23123
(integer) 1
hget:查看指定哈希表中指定字段的值。
192.168.201.6:6379> hget age 1
"23123"
(3)其他
del:删除一个或多个键
192.168.201.6:6379> del lisi
(integer) 1
exists:查看键是否存在
192.168.201.6:6379> exists age
(integer) 1 #存在
192.168.201.6:6379> exists ages
(integer) 0 #不存在
type:返回键存储类型
192.168.201.6:6379> type age
hash
keys:查找所有符合给定模式的键,因为他会遍历扫描键空间,可能造成阻塞,所以生产环境慎用
192.168.201.6:6379> keys * #匹配所有
1) "name1"
2) "age"
192.168.201.6:6379> keys a* #匹配a开头的所有
1) "age"
192.168.201.6:6379> keys a? #匹配a开头,后面一个字符
1) "ai"
192.168.201.6:6379> keys a?? #匹配a开头,后面两个字符
1) "age"
expire:给键设定过期时间。生命周期(以秒为单位)
192.168.201.6:6379> expire ai 1000
(integer) 1
ttl:查看键过期时间,-1表示永不过期,-2表示已过期
192.168.201.6:6379> ttl ai
(integer) 990
rename:重命名键名称(如果重命名的新名字已存在有键,则直接覆盖)
192.168.201.6:6379> rename ai aiw
OK
renamenx:重命名,但不进行覆盖
192.168.201.6:6379> renamenx lisi name
(integer) 0
dbsize:查看键数量
192.168.201.6:6379> dbsize
(integer) 3
move:移动数据到指定库
192.168.201.6:6379> keys *
1) "name1"
2) "name"
192.168.201.6:6379> move name 1
(integer) 1
192.168.201.6:6379> keys *
1) "name1"
192.168.201.6:6379> select 1
OK
192.168.201.6:6379[1]> keys *
1) "name"
flushdb:清空当前数据库数据
192.168.201.6:6379[1]> flushdb
OK
192.168.201.6:6379[1]> keys *
(empty array)
fulushall:清空所有数据库的数据,慎用!
五、启停脚本,简单写一个控制脚本,赋予执行的权限,将脚本文件移动到/usr/bin/,保证所有用户都可以执行
#!/bin/bash
read -p '请输入redis服务端口:' port
ml="/usr/local/redis/"
if
[ -f $ml'conf'/$port'.conf' ]; then
if
[ "$1" = "start" ]; then
redis-server $ml'conf'/$port'.conf'
elif
[ "$1" = "stop" ]; then
cat $ml'/run/redis_'$port'.pid' &> /dev/null
if [ $? != 0 ]; then
echo 未启动此服务,不用关闭......
else
tar zcvf $ml'data/'$port.rdb-$(date +%s).tar.gz $ml'data/'$port'.rdb' &> /dev/null &&
pid=$(cat $ml'run/redis_'$port'.pid')
kill "$pid"
fi
elif
[ "$1" = "restart" ]; then
cat $ml'run/redis_'$port'.pid' &> /dev/null
if [ $? = 0 ]; then
tar zcvf $ml'data/'$port.rdb-$(date +%s).tar.gz $ml'data/'$port'.rdb' &> /dev/null &&
pid=$(cat $ml'run/redis_'$port'.pid')
kill $pid &&
redis-server $ml'conf/'$port'.conf'
else
redis-server $ml'conf/'$port'.conf'
fi
else
echo "USEAGE: $0 start | stop | restart"
fi
else
echo 配置文件不存在
fi
[root@localhost ~]# chmod +x redis
[root@localhost ~]# mv redis /usr/bin
六、redis持久化
1、redis只要开启了进程则默认开启了持久化的配置,数据直接存储在他的安装目录下生成数据文件,如果不进行修改,则所有进程的数据都默认存储在dump.rdb中,所以我们需要在每个配置文件中进行相应的修改
2、这是控制RDB半持久化的配置文件,半持久化也就是不定期通过异步方式保存到磁盘,默认3600 秒(1 小时)内至少有一个键被修改,Redis 会保存一个快照;300 秒(5 分钟)内至少有 100 个键被修改,Redis 会保存一个快照;60 秒内至少有 10000 个键被修改,Redis 会保存一个快照。如果需要改动,可以取消440行注释,自己进行定义。同时save也是一个在redis数据库中直接进行使用作用是保存的工具
3、这是控制AOF全持久化的配置文件,全持久化也就是每一次数据变化都写入一个append only file文件,默认是关闭状态,需要启用可以将里面的no改成yes,启用之后,下次登录redis使用的时候,会自动在数据目录下生成对应的记录文件目录
[root@localhost data]# ls
6379.rdb appendonlydir dump.rdb
[root@localhost data]# cd appendonlydir/
[root@localhost appendonlydir]# ls
appendonly.aof.1.base.rdb appendonly.aof.1.incr.aof appendonly.aof.manifest
- 数据损坏模拟实验(实验结果未达到理想要求,请慎用!!!)
总结:如果aof数据损坏,只需要关闭aof功能选项,那么备份存储的rdb文件可以恢复数据库数据,但因为aof备份文件是记录操作步骤的文件,所以无法直接恢复aof中的数据。但如果是rdb文件损坏,而aof备份文件保存完整,在重启的时候会直接优先读取aof备份文件,最后完成数据的修复。注意:在对数据操作过程中,一定做好数据备份,避免形成不可避免的损失。
1、尝试对aof文件进行修复实验
[root@localhost data]# cd appendonlydir/
[root@localhost appendonlydir]# ls
appendonly.aof.1.base.rdb appendonly.aof.1.incr.aof appendonly.aof.manifest
[root@localhost appendonlydir]# vim appendonly.aof.1.incr.aof
*24964156464
$6
SELECT
$1
0
*3
$3
set
$4
name
$8
chensong
*3
$3
set
$3
age
$2
28
重启服务,发现无法重连
[root@localhost bin]# redis restart
请输入redis服务端口:6379
/usr/bin/redis: 第 22 行:kill: (13273) - 没有那个进程
[root@localhost bin]# redis-cli -h 192.168.201.6
Could not connect to Redis at 192.168.201.6:6379: Connection refused
not connected> exit
[root@localhost bin]# pgrep redis #显示没有进程
尝试修复aof文件,这个输出消息提示加上--fix选项尝试修复
[root@localhost bin]# redis-check-aof /usr/local/redis/data/appendonlydir/appendonly.aof.1.incr.aof
Start checking Old-Style AOF
0x 21: Expected prefix '$', got: '*'
AOF analyzed: filename=/usr/local/redis/data/appendonlydir/appendonly.aof.1.incr.aof, size=100, ok_up_to=0, ok_up_to_line=6, diff=100
AOF /usr/local/redis/data/appendonlydir/appendonly.aof.1.incr.aof is not valid. Use the --fix option to try fixing it.
此过程是提示对文件进行缩减,请谨慎!!!
[root@localhost bin]# redis-check-aof --fix /usr/local/redis/data/appendonlydir/appendonly.aof.1.incr.aof
Start checking Old-Style AOF
0x 21: Expected prefix '$', got: '*'
AOF analyzed: filename=/usr/local/redis/data/appendonlydir/appendonly.aof.1.incr.aof, size=100, ok_up_to=0, ok_up_to_line=6, diff=100
This will shrink the AOF /usr/local/redis/data/appendonlydir/appendonly.aof.1.incr.aof from 100 bytes, with 100 bytes, to 0 bytes
Continue? [y/N]:
- 损坏aof文件,直接使用rdb进行登录,可以恢复数据库数据,但无法恢复aof数据(如果一定要恢复,可以尝试手动恢复)
[root@localhost appendonlydir]# rm appendonly.aof.1.incr.aof
rm:是否删除普通文件 "appendonly.aof.1.incr.aof"?Y
#此时服务虽然重启,可是由于开启aof,而没有aof文件,导致连接失败
[root@localhost appendonlydir]# redis restart
请输入redis服务端口:6379
[root@localhost appendonlydir]# redis-cli -h 192.168.201.6
Could not connect to Redis at 192.168.201.6:6379: Connection refused
not connected> exit
#关闭aof
[root@localhost appendonlydir]# redis restart
请输入redis服务端口:6379
[root@localhost appendonlydir]# redis-cli -h 192.168.201.6
192.168.201.6:6379> keys *
1) "name1"
2) "name"
3、如果损坏的是rdb文件,直接利用aof进行修复
#这是当前库数据
[root@localhost appendonlydir]# redis-cli -h 192.168.201.6
192.168.201.6:6379> keys *
1) "name1"
2) "name"
#直接删除rdb文件模拟他的损坏
[root@localhost data]# rm -rf 6379.rdb
#这种情况直接使用我们重启脚本,有未知问题
[root@localhost appendonlydir]# redis restart
请输入redis服务端口:6379
kill: 用法:kill [-s 信号声明 | -n 信号编号 | -信号声明] 进程号 | 任务声明 ... 或 kill -l [信号声明]
[root@localhost run]# cat redis_6379.pid
21520
[root@localhost run]# kill 21520
[root@localhost run]# cat redis_6379.pid
cat: redis_6379.pid: 没有那个文件或目录
[root@localhost appendonlydir]# redis start
请输入redis服务端口:6379
[root@localhost data]# ls
- rdb #重启服务,自动创建rdb文件
[root@localhost appendonlydir]# redis-cli -h 192.168.201.6
192.168.201.6:6379> keys *
1) "name1"
2) "name"