配置文件
-
网络配置
-
port : 6379 默认 指定redis所使用的端口
-
bind 配置客户端连接redis服务时,所能使用的redis服务 默认redis所在主机的网卡上任意一个IP地址
redis-server redis.conf & (服务端)
redis-cli -h hostlocal -p port [shutdow] (客户端)(打开和关闭都需要端口号和IP地址)
-
tcp-keepalive 300 服务端多就向客户端发一次虚拟请求,如果没有响应,就挂了(TCP连接保活策略)如果是0就关闭
-
-
常规配置
-
loglevel : 日志级别,开发阶段debug,生产阶段noctice或者warning
-
logfile : 指定日志文件,redis在运行过程中会输出一些日志信息,默认情况会输出到控制台(logfile:"")
-
database 默认数据库个数
-
-
安全配置
只要有端口号和IP地址就行,安全性没有MySQL安全,但是效率高的一批
-
requirepass 连接密码,默认是没有密码的,需要先配置protected-mode=yes 登录时候加上 -a passwd ,以后每次发请求就需要验证,就,失去了高效性
-
-
RDB配置
默认情况下有三种:①一分钟改变一万次。②五分钟改变了十万次。③十五分钟改变了一次
-
save <second> <changes> save 900 1 save 300 10 save 60 10000
-
stop-writes-on-bgsave-error : 当bgsave 快照操作出错时停止写数据到磁盘,这样能保证内存数据和磁盘数据的一致性,但如果不在乎这种一致性,要在 bgsave 快照操作出错时继续写操作,这里需要配置为no。
-
rdbcompression:设置对于存储到磁盘中的快照是否进行压缩,设置为yes时,Redis 会采用LZF算法进行压缩;如果不想消耗CPU进行压缩的话,可以设置为no,关闭此功能。
-
rdbdhecksum:在存储快照以后,还可以让Redis使用CRC64算法来进行数据校验,但这样会消耗一定的性能,如果系统比较在意性能的提升,可以设置为no,关闭此功能。
-
dbfilename: Redis持久化数据生成的文件名,默认是dump.rdb,也可以自己配置。
-
dir: Redis持久化数据生成文件保存的目录,默认是./即redis的启动目录,也可以自己配置。
-
-
AOF配置
-
appendonly:配置是否开启AOF,yes表示开启,no表示关闭。默认是no,效率太低了呀。
-
appendfilename: AOF保存文件名
-
appendfsync: AOF异步持久化策略
-
always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差但数据完整性比较好(慢,安全)
-
everysec:出厂默认推荐,每秒异步记录一次(默认值)、
-
no:不即时同步,由操作系统决定何时同步。
-
-
no-appendfsync-on-rewrite:重写时是否可以运用appendsync,默认no,可以保证数据的安全性。
-
auto-aof-rewrite-percentage:设置重写的基准百分比
-
auto-aof-rewrite-min-size:设置重写的基准值
-
持久化
redis数据是在内存中(万一不小心关机了,信息就没了),保存到磁盘里面就是持久化,所以有两个策略:RDB和AOF两个策略,每次启动时候就可以把磁盘上的数据,加载到内存中。
-
RDB策略
在指定时间间隔内,redis执行指定次数的写操作会自动触发一次持久化
redis 服务开启时,这种持久化策略就是存在的,(开机自启)
最后写的几条数据会计不上,所以要有AOF
-
AOF策略
采用操作日志来记录在redis服务上的每一次写操作(记录命令)
每次redis服务启动时,都会重新执行一遍操作日志中的指令(不是默认的策略,效率不高)
总结:如果特别重要就需要开启,一般开启RDB就够了,大多数数据都在关系型数据库里面,redis就是因为他快,所以放在redis里面,就是因为快而已,丢失就丢失了,从关系型数据库再复制一下就行了
事务
事务:把一组数据库命令放在一起执行,来保证这一组操作的原子性,要么同时成功要么同时失败
redis的事务:允许把一组redis命令放在一起执行,但是没有全部原子性,强调的是序列化,然后一起执行,保证部分原子性
-
multi : 标记事务的开始
-
exec : 执行事务队列中所有的redis命令
-
discard : 清除压入队列的命令,并且结束整个事务
-
watch : 监控一个键值,当事务在执行过程中,此键值代码的值发生变化,那么事务放弃执行,否则,正常
-
unwatch : 放弃监控所有的键值
127.0.0.1:6379> multi OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> zadd k2 28 name QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> keys * QUEUED 127.0.0.1:6379> exec 1) OK 2) (integer) 1 3) OK 4) 1) "k2" 2) "k1" 3) "zset" 127.0.0.1:6379> keys * 1) "k2" 2) "k1" 3) "zset" #discard 127.0.0.1:6379> multi OK 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> set k4 v4 QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> exec (error) ERR EXEC without MULTI 127.0.0.1:6379> keys * 1) "k2" 2) "k1" #watch 127.0.0.1:6379> set balance 100 OK 127.0.0.1:6379> set balance2 1000 OK 127.0.0.1:6379> set version 1 OK 127.0.0.1:6379> watch version OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> decrby balance 50 QUEUED 127.0.0.1:6379> incrby balance 50 QUEUED 127.0.0.1:6379> incr version QUEUED 127.0.0.1:6379> exec 1) (integer) 50 2) (integer) 100 3) (integer) 2 #如果这里新开一个客户端,incr version 那么exec之后就会发生nil,就不干了(当然,没人用redis去实现这么复杂的逻辑,否则太傻逼了)
redis事务只能保证部分的原子性:
-
如果一组命令在压入事务队列的时候报错了,那么本事务中所有的命令都不执行,这样就是事务的原子性(语法错误)
127.0.0.1:6379> multi OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> seta k3 k4 (error) ERR unknown command `seta`, with args beginning with: `k3`, `k4`, 127.0.0.1:6379> exec (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> keys * (empty array) 127.0.0.1:6379>
-
压入队列没有错误,但是执行事务队列命令时候出错了,那么只有报错的命令不会执行,别的事务队列命令是可以执行的(没有保证事务的原子性)(语义错误)
127.0.0.1:6379> multi OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> incr k1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> exec 1) OK 2) (error) ERR value is not an integer or out of range 3) OK 127.0.0.1:6379> keys * 1) "k2" 2) "k1"
总结:
-
单独的隔离操作:事务中的所有命令都会序列化、顺序地执行。事务在执行过程中,不会被其它客户端发来的命令请求所打断。除非使用watch命令监控。
-
不保证事务的原子性: redis同一个事务中如果一条命令执行失败,其后的命令仍然可能会被执行,redis 的事务没有回滚。Redis 已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为Redis不需要事务回滚的能力。
-
消息的发布与订阅
redis客户端订阅频道,消息的发布者在频道上发布消息,所有订阅了频道的客户端都能收到这个消息。
-
subscribe : 订阅一个或者多个频道的消息
subscribe ch1 ch2 ch3 ch4 等等,等消息
-
publish : 将消息发送到指定频道
publish ch1 hello
-
psubscribe : 订阅一个或者多个频道的信息,但是可以使用通配符
主从复制
服务器的集群:假如很多请求,那么我们可以弄很多redis服务器,那么redis服务器比较闲我们就用哪一台,写少读多。写的是主库,从库(读的)的数据和主库一致,所以主从复制
多主多从:主少从多,主写从读,主写从读,主写同步复制到从。
搭建一主二从的redis集群:
-
搭建三个redis服务,一个主两个从(同一个服务器启动三次redis-server ,port不同就行了)
-
生成多个conf文件多次启动,需要修改bind ,port,pidfile,logfile ,dbfilename
-
启动 redis-server redis6380.conf &
-
-
通过客户端分别连接
-
查看三台redis服务在集群中的主从角色:info replication
默认情况下所有服务器都是主机(master),都能进行读写,但是都没有从机
-
现在6379上写操作
然后发现只有在6379服务器上有keys 6380和6381没有keys
-
设置主从关系:设主不设从
-
在6380上执行 : slaveof 127.0.0.1 6379 这样 role:slave 变成了从机
-
在6381上执行:同上,
-
看6379 上的info replication
-
此时再看6380和6381上的keys 就会发现已经同步过来了。
127.0.0.1:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=126,lag=0 slave1:ip=127.0.0.1,port=6381,state=online,offset=126,lag=0 master_replid:73eccb8f456dd5c94df7e30e70bb1b88d8c4f300 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:126 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:126
-
-
全量复制:一旦主从关系确定,会自动把主机上已有的数据同步复制到从库(看5.4)
-
增量复制:主机添加数据会自动同步到从库上
往6379上新加数据set k2 v2
-
在6380或者6381上执行set,主写从读(从机只能读,不能写)
127.0.0.1:6380> set k1 v1 (error) READONLY You can't write against a read only replica. 127.0.0.1:6380>
-
如果主机宕机:从机原地待命,等待主机(此时可以读,但是数据不会更新)
-
关闭6379服务:redis-cli -h 127.0.0.1 -p 6379 shutdown
-
查看从机的服务信息info replication
127.0.0.1:6380> info replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:down # 没有连接 master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:2082 master_link_down_since_seconds:22 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:73eccb8f456dd5c94df7e30e70bb1b88d8c4f300 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2082 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:2082 127.0.0.1:6380> get k1 "v1"
-
主机恢复之后(重启6379命令)就和之前一样了,没什么问题了
-
-
从机宕机:主机少一个从机,其他从机没什么变化
-
关闭6380
-
查看6379的主从角色
-
从机恢复:变成了主机而且没有从机(重新设置主从关系)再次执行slaveof 127.0.0.1 6379
root@VM-16-3-centos ~]# redis-cli -h 127.0.0.1 -p 6381 127.0.0.1:6381> info replication # Replication role:master #变成了主机 connected_slaves:0 master_replid:84de9a1322cbe63151bad5716af6c528cb4cab62 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6381>
-
-
从机上位:
-
主机宕机,从机原地待命(主机修好了,就可以重新上位)
-
如果修不好主机了,就需要从机上位当主机
-
断开主从关系:在从机上执行slaveof no one
-
重新设置主从关系:在6381上执行slaveof 127.0.0.1 6380
-
-
主机有恢复了,变成了独立的服务器,有利于整个集群,就可以加入集群了呀,去当从机(小弟)在6379上执行slaveof 127.0.0.1 6381
-
1主机,2是1的从机,3是2的从机,这样2是主机也是从机,但是他不能写数据
-
总结:一台主机配置多台从机,一台从机配置多台从机,形成一个庞大的集群结构,但是增加了服务间的延迟时间
哨兵模式
解决主从模式的缺点:主机宕机了我们也不知道啊,从机不知道啊,而且集群多的时候很麻烦,很多从机都重新找主机去了
哨兵模式就是机器执行上面的操作就行了:主要告诉哨兵我的主机是谁就行了(主机宕机,从机上位的自动版)
-
搭建一主二从的集群模式
-
配置一个哨兵配置文件
-
在redis安装目录下写一个配置文件:redis_sentinel.conf 并编辑内容为:sentinel monitor dc-redis 127.0.0.1 6379 1
表示:在指定监控主机的IP地址和port端口,得到哨兵的投票数(当哨兵投票数大于等于次数来进行切换),其实会找到一个性能最好的从机。
-
新开窗口,启动哨兵:redis-sentinel 配置文件 哨兵的端口是 26379
-