下面罗列出于安全需要考虑的一些事项
1.禁止一些高危命令
修改 redis.conf 文件,添加一下命令来禁用远程修改 DB 文件地址
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command SHUTDOWN ""
rename-command CONFIG ""
rename-command EVAL ""
2.以低权限运行 Redis 服务
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆
创建一个redis账户,然后通过该账户启动redis,命令如下:
su - redis -c " /redis/bin/redis-server /redis/etc/redis.conf"
使用进程查看ps aux|grep redis-server可见进程以redis运行
redis 3384 0.8 0.1 137440 4168 ? Ssl 17:43 0:00 /redis/bin/redis-server 192.168.196.133:6379
3.为 Redis 添加密码验证
修改 redis.conf 文件,添加
requirepass mypassword
4.禁止外网访问 Redis
修改 redis.conf 文件,添加或修改
bind 192.168.255.111 #本机ip
注:bind的意思不是绑定外部服务器的IP,而是绑定本机可以接受访问的IP
最好使用防火墙来开放固定ip
#例如只允许192.168.1.*这一段C类地址访问,其他IP地址禁止访问:
#只允许192.168.255.112访问 tcp 6379端口
firewall-cmd --zone=public --add-rich-rule 'rule family="ipv4" source address="192.168.255.112" port port=6379 protocol=tcp reject' --permanent
#重启
systemctl restart firewalld.service
#查看配置结果
firewall-cmd --list-all
5.redis可考虑换其他端口不要6739
6.数据加密支持
因为 Redis 不支持加密. 想要在互联网/或不可信网络上实现加密传输, 就需要额外的保护层, 例如SSL代理。我们推荐使用 spiped。
7.字符串转义和NoSQL注入
应用程序应该避免将不受信任来源的字符串, 当做Lua脚本来执行。
8.清除历史里的密码:
foo@bar:~$ rm .rediscli_history
foo@bar:~$ ln -s /dev/null .rediscli_history
foo@bar:~$ redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> exit
foo@bar:~$ ls -al .rediscli_history
lrwxrwxrwx 1 foo foo 9 Sep 30 00:19 .rediscli_history -> /dev/null
9.设置Redis最大占用内存
设置maxmemory参数,一般推荐Redis设置内存为最大物理内存的四分之三
[root@localhost redis]# vi redis.conf
#例如:本机自带内存只有1G,所以设置0.75G,换成byte是751619276
# maxmemory <bytes>
maxmemory 751619276
10.主从配置
主数据库可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数据库。而从数据库一般是只读的,并接受主数据库同步过来的数据。
##比如现有如下3台实例
#192.168.255.111 主
#192.168.255.112 从
#192.168.255.113 从
#主节点无需配置slaveof , 修改两个从节点配置文件
[root@localhost redis]# vi redis.conf
#slaveof参数的格式如 masterip主节点ip masterport主节点端口
#slaveof <masterip> <masterport>
slaveof 192.168.255.111 6379
#如果master服务器设置有密码则需要配置masterauth参数。各个节点的密码都必须一致
#masterauth <master-password>
masterauth 123456
#启动
[root@localhost redis]# src/redis-server ./redis.conf
#查看效果
[root@localhost redis]# src/redis-cli -h 192.168.255.111
192.168.255.111:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.255.112,port=6379,state=online,offset=13086250,lag=1
slave1:ip=192.168.255.113,port=6379,state=online,offset=13086250,lag=1
master_replid:dcb0aea47bd9c540a1359c709170f413dfc3e922
master_replid2:bfd7df000877bc0a858e753de571436408718ee5
master_repl_offset:13086250
second_repl_offset:11574
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:12037675
repl_backlog_histlen:1048576
[root@localhost redis]# src/redis-cli -h 192.168.255.113
192.168.255.113:6379> info replication
# Replication
role:slave
master_host:192.168.255.111
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:13078489
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:dcb0aea47bd9c540a1359c709170f413dfc3e922
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:13078489
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:12029914
repl_backlog_histlen:1048576
11.哨兵配置
哨兵的作用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。
##部署三个哨兵三台机器配置一样即可
#要注意的是bind 要改为本机地址
[root@localhost redis]# vi sentinel.conf
#本机地址
port 26379
bind 192.168.255.111 #本机地址
dir "/usr/local/redis/tmp"
sentinel monitor mymaster 192.168.255.111 6379 1 #mymaster是集群的名称可自定义,IP地为集群中master的地址,注意与bind的区别 6379表示端口 1表示 需要1个哨兵同意才能执行故障转移操作
sentinel down-after-milliseconds mymaster 30000 #超过多少毫秒跟一个redis实例断了连接,哨兵就可能认为这个redis实例挂了
sentinel failover-timeout mymaster 60000 #failover转移时间,超出此时间认为master转移失效,重新开始转移
sentinel parallel-syncs mymaster 1 #新的master别切换之后,同时有多少个slave被切换到去连接新master,重新做同步,数字越低,花费的时间越多
protected-mode yes #关闭安全模式,否则会报错
sentinel auth-pass mymaster 123456 #如果集群设置了密码,需要添加
logfile /usr/local/redis/logs/sentinal.log #日志路径
#启动哨兵
[root@localhost redis]# src/redis-sentinel ./sentinel.conf &
#查看进程是否启动
[root@localhost redis]# ps -ef|grep redis
12.cluster集群相关
搭建
[root@localhost redis]# vi redis.conf
cluster_enabled true
cluster-config-file /usr/local/redis/logs/nodes-6379.conf #6379改为各自的端口
cluster-node-timeout 15000
firewall-cmd --zone=public --add-port=17000/tcp --permanent
firewall-cmd --zone=public --add-port=17001/tcp --permanent
firewall-cmd --reload
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis
错误redis requires ruby version >=2.2.2的解决方案
https://blog.csdn.net/saafdgvsdg/article/details/80699952
(1) [root@linux ~]# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
(2) [root@linux ~]# curl -sSL https://get.rvm.io | bash -s stable
(3) [root@linux ~]# find / -name rvm -print
(4)[root@linux ~]# source /usr/local/rvm/scripts/rvm (路径以上图中最后的为主)
(5) [root@linux ~]# rvm list known (查看rvm库中已知的ruby版本)
(6) [root@linux ~]# rvm install 2.4.1 (安装一个ruby)
(7) [root@linux ~]# rvm use 2.4.1 (使用一个ruby版本:)
(8) [root@linux ~]# rvm use 2.4.1 --default (设置ruby2.4.1为默认的ruby)
(9) [root@linux ~]# ruby --version (查看ruby版本)
创建集群
src/redis-trib.rb create --replicas 1 192.168.255.111:6379 192.168.255.111:6380 192.168.255.112:6379 192.168.255.112:6380 192.168.255.113:6379 192.168.255.113:6380
#错误解决办法:ERR Slot 741 is already busy
#用redis-cli登录到每个节点执行flushall和cluster reset就可以了
#redis创建集群失败——can't connect to node 192.168..
#bind 改成本机ip 如192.168.255.113 127.0.0.1
#MOVED 5798 192.168.255.112:6379
#redis/src/redis-cli -p 6379 -c
#错误处理
[ERR] Node 172.168.63.202:7001 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解决方法:
1)、将需要新增的节点下aof、rdb等本地备份文件删除;
2)、同时将新Node的集群配置文件删除,即:删除你redis.conf里面cluster-config-file所在的文件;
3)、再次添加新节点如果还是报错,则登录新Node,./redis-cli–h x –p对数据库进行清除:
172.168.63.201:7001> flushdb #清空当前数据库
先把节点都加入到集群中,之后再做加密
##集群密码设置
#方式一:修改所有redis集群中的redis.conf,此方式需要重启所有节点
[root@localhost redis]# vi redis.conf
masterauth 123456
requirepass 123456
#方式一:进入各个实例进行设置,此方式不需要重启
[root@localhost redis]# src/redis-cli -c -h 192.168.156.113 -p 6379-a 123456
192.168.156.113:6379>config set masterauth 123456
192.168.156.113:6379>config set requirepass 123456
192.168.156.113:6379>auth 123456
192.168.156.113:6379>config rewrite
#连接集群节点 要加-c
src/redis-cli -h 192.168.126.7 -p 7000 -a 123456 -c
设置密码之后如果需要使用redis-trib.rb的各种命令
如:redis-trib.rb check 127.0.0.1:7000,则会报错ERR] Sorry, can’t connect to node 127.0.0.1:7000
解决办法:
修改gem的redis工具下的一个文件client.rb,对应内容如下:
:password => "123456", #指定redis登录密码
(一般默认路径/usr/lib/ruby/gems/1.8/gems/redis-3.2.1/lib/redis/client.rb,另可通过命令find / -name client.rb进行全盘搜索)
关于集群命令
https://blog.csdn.net/u012099568/article/details/79419422
https://www.cnblogs.com/xlxue/p/7777257.html
13.关于脑裂
概念:某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着
此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master
这个时候,集群里就会有两个master
修改redis.conf文件
min-slaves-to-write 3
min-slaves-max-lag 10
要求至少有3个slave,数据复制和同步的延迟不能超过10秒
如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了
上面两个配置可以减少异步复制和脑裂导致的数据丢失
14.缓存降级
服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。
15.关于Redis的requirepass和masterauth密码的设置问题
建议redis启用密码时将各个节点的masterauth和requirepass设置为相同的密码,降低运维成本。当然设置为不同也是可以的,注意slave节点masterauth和master节点requirepass的对应关系就行。
16.redis持久化备份及备份恢复
redis有两种持久化策略
①.RDB(默认开启)
优点:启动时间会更短
缺点:会丢失最后一次快照后的内容
SAVE命令:会阻塞主进程
BGSAVE命令:使用BGSAVE的话redis会fork出一个子进程来执行快照操作,而不影响主进程
默认的redis.conf配置文件说明
[root@localhost redis]# cat redis.conf
save 900 1 # 900秒内有至少1个键被更改则进行快照
save 300 10 # 300秒内有至少10个键被更改则进行快照
save 60 10000 # 60秒内有至少10000个键被更改则进行快照
dir "/usr/local/redis"
#定时脚本为
#!/bin/bash
echo "start..."
sdate=$(date "+ %Y-%m-%d %H:%M:%S")
msg=`/usr/local/redis/src/redis-cli -h 192.168.255.111 -p 6379 bgsave`
echo "start bgsave time:$sdate"
result=`/usr/local/redis/src/redis-cli -h 192.168.255.111 -p 6379 info Persistence | grep "rdb_bgsave_in_progress" | awk -F":" '{print $2}'`
while [ `echo ${result} | awk -v tem="0" '{print($2>tem)? "1":"0"}'` -eq "1" ] ; do
sleep 1
result=`/usr/local/redis/src/redis-cli -h 192.168.255.111 -p 6379 info Persistence | grep "rdb_bgsave_in_progress" | awk -F":" '{print $2}'`
done
edate=$(date "+ %Y-%m-%d %H:%M:%S")
echo "end bgsave time:$edate"
echo "renaming rdb file..."
date=$(date "+ %Y%m%d")
cp "/usr/local/redis/dump.rdb" "/usr/local/redis/snapshots/${date}.rdb"
echo "finish backup rdb file"
echo "end"
#加入定时任务
0 0 * * * usr/local/redis/redis-backup.sh >> /usr/local/redis/logs/backup.txt
②AOF持久化
优点:数据一般不会丢失
缺点:持久化文件会变得越来越大,恢复时间较慢
##配置
dir /home/redis/data_6379/
appendonly yes #启用AOF持久化方式
appendfilename appendonly.aof #AOF文件的名称,默认为appendonly.aof
# appendfsync always #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。
appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。
# appendfsync no #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。
##恢复
#拷贝 AOF 文件到 Redis 的数据目录
cp appendonly.aof /home/redis/data_6379/
#重启
redis-server redis_6379.conf
③官方建议:
通常,如果你要想提供很高的数据保障性,那么建议你同时使用两种持久化方式。
如果你可以接受灾难带来的几分钟的数据丢失,那么你可以仅使用RDB。
很多用户仅使用了AOF,但是我们建议,既然RDB可以时不时的给数据做个完整的快照,并且提供更快的重启,所以最好还是也使用RDB。
目前比较流行的方案是Master上Snapshot和AOF都不做,来保证Master的读写性能,而Slave上则同时开启Snapshot和AOF来进行持久化,保证数据的安全性,也可以考虑将save中的频率调高一些或者调用一个计划任务来进行定期bgsave的快照存储,来尽可能的保障本地化数据的完整性。
④优先级如下:
1.如果只配置 AOF ,重启时加载 AOF 文件恢复数据;
2.如果同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据;
3.如果只配置 RDB,启动是将加载 dump 文件恢复数据。