redis
redis概述
性能极高,读可以读11万次,写可以写8.1w次
先存到内存中,每过一段时间持久化
在linux上安装redis
redis常用命令
set 创建key键
get 查看key键
mset 批量创建key键
mget 批量查询key键
del 删除key键
select * 切换数据库
dbsize 查看当前数据库大小
exists * 判断某个键是否存在
keys * 查看当前数据库所有键
set/get 创建key键/查询key键
set
get
127.0.0.1:6379> set firstname zheng #创建key键并加字符串
OK
127.0.0.1:6379> get firstname #查看字符串
"zheng"
127.0.0.1:6379> del firstname #删除key键
(integer) 1
127.0.0.1:6379> keys * #查看当前数据库所有key键
(empty array)
127.0.0.1:6379> get firstname #查看之前创建的key键
(nil)
mset
mget
127.0.0.1:6379> mset key1 11 key2 22 key3 33 #批量创建key1、key2、key3这三个键并加入字符串
OK
127.0.0.1:6379> keys * # 查看所有键
1) "key2"
2) "key1"
3) "key3"
127.0.0.1:6379> mget key1 key2 key3 # 批量查询三个键
1) "11"
2) "22"
3) "33"
dbsize 查看数据库大小
#查看当前数据库大小,显示5表示有五个键
127.0.0.1:6379> dbsize
(integer) 5
127.0.0.1:6379> keys * #查看当前数据库所有键
1) "key:__rand_int__"
2) "counter:__rand_int__"
3) "name"
4) "myhash"
5) "mylist"
select 切换数据库
#切换到3号数据库,在切换到第一个数据库,第一个数据库是0!
127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> dbsize
(integer) 0
127.0.0.1:6379[3]> select 0
OK
127.0.0.1:6379> dbsize #表示有5个key键
(integer) 5
exists 查询键是否存在
#有显示1,没有则显示0
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists name1
(integer) 0
move 移动
移动name这个键到1号数据库中,当前是0号数据库
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> exists name #判断key不存在了
(integer) 0
127.0.0.1:6379> select 1 #切换到1号数据
OK
127.0.0.1:6379[1]> exists name #key键存在1号数据库中
(integer) 1
设置和查看过期时间
expire
ttl
- expire 设置过期时间 ()
- ttl 查询过期时间
EXPIRE 接口定义:EXPIRE key “seconds”
接口描述:设置一个key在当前时间"seconds"(秒)之后过期。返回1代表设置成功,返回0代表key不存在或者无法设置过期时间。
TTL 接口定义:TTL key
接口描述:获取key的过期时间。如果key存在过期时间,返回剩余生存时间(秒);如果key是永久的,返回-1;如果key不存在或者已过期,返回-2。
#设置name键过期时间为10秒
127.0.0.1:6379[1]> expire name 10
(integer) 1
127.0.0.1:6379[1]> ttl name
(integer) 6
127.0.0.1:6379[1]> ttl name # 还剩4秒过期
(integer) 4
127.0.0.1:6379[1]> ttl name # -2表示已过期
(integer) -2
127.0.0.1:6379[1]> exists name #过期以后判断当前key是否存在
(integer) 0
type 查看当前key键的数据类型
查看name这个键的类型为string类型
127.0.0.1:6379[1]> keys *
1) "name"
127.0.0.1:6379[1]> type name
string
flushdb/flushall
关闭redis服务
redis-benchmark性能测试
测试100个并发连接,每个并发10w个请求
[root@redis-master ~]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000
五大数据类型
String(字符串)
APPEND 追加字符串
APPEND追加字符串,如果当前key不存在则创建key,相当于linux里的touch
STRLEN 获取字符串的长度
incr/decr,incrby/decrby 增加减少浏览量
ince增加1浏览量,decr减少1浏览量
INCRBY可以指定增加多少,DECRBY可以指定减少多少
get查看
getrange/setrange 截取字符串/替换指定位置开始的字符串
#截取
127.0.0.1:6379> set key1 hello,123456!!!
OK
127.0.0.1:6379> getrange key1 0 4 #显示0到4的字符
"hello"
127.0.0.1:6379> getrange key1 0 -1 #0到-1表示显示所有字符串
"hello,123456!!!"
127.0.0.1:6379> getrange key1 5 11 #显示第6个到第12个字符串
",123456"
#替换
127.0.0.1:6379> set key2 123456
OK
127.0.0.1:6379> get key2
"123456"
127.0.0.1:6379> SETRANGE key2 0 3333 #从第一个字符开始替换4个字符
(integer) 6
127.0.0.1:6379> get key2 #从第一个到第四个字符都变成了3
"333356"
setex/setnx 设置过期时间/不存在再设置
设置分布锁的时候用
msetnx 一个原子性的操作
要么一起成功,要么一起失败,不可能有这个创建成功了,那个创建失败了
下面因为k1已经创建过了,所有key5就跟着创建失败了
127.0.0.1:6379> msetnx key1 123 key5 555
(integer) 0
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
3) "key3"
127.0.0.1:6379> get key1
"11"
127.0.0.1:6379> get key5
(nil)
对象
平常都是把数据直接写进字符串,但是redis的key不一样,他可以用冒号这种字符来分割
比如加入用户的姓名年龄等,user:1:name 字符串写姓名 user:1:age 字符串写年龄
getset 设定值并返回旧值
设定 key 的值为 volue ,并返回 key 的旧值 (old volue)
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> getset db mysql
"redis"
127.0.0.1:6379> get db
"mysql"
List
可以把list理解成一个桶,第一个写入的就是在桶的最下面也就是最后一个,最新添加的也就是第一个
lpush/rpush 插入值
lpush从头添加
rpush从最后添加
lrange 获取list值
lpop/rpop 移除list某一个值
lindex 获取list某一个值
llen 返回列表长度
lrem 移除list中指定个数的value,精准匹配
trim 截取list中指定的长度
rpoplpush 移除列表最后一个元素到新的列表中
把第一个列表中的最后一个元素移出,移动到新的列表中,没有的话自动创建
lset 把指定下标替换成另一个值,更新操作
linsert 将某个value插入到列表中某个元素的前面或后面
before插入到元素前面,把other插入到world前面
after插入到元素后面,把new插入到world后面
这里在redis中输入linsert以后就会有提示
小结
Set(无序集合)
Set 是 String 类型的无序集合,集合成员是唯一的,所以set中的值是不能重复的,只存在唯一
sadd 在set集合中添加元素
sadd 添加元素
smembers 查看指定set的所有值
sismember 判断某个值在不在set集合中
scard 获取set集合中元素个数
srem 移除set集合中制定元素
srem 移除掉myset集合中的hello元素
scard获取元素个数
smembers 查看set集合中所有值
srandmember 随机抽取元素
抽随机数的时候可以用,也可以选择随机抽取几个随机数
spop 删除指定/随机的key
smove 将一个值移到另一个set集合中
smove 将myset集合中kuangshen移动到myset2集合中
数字集合类
- 差集 —— 两个集合中不一样的地方
- 交集 —— 两个集合中一样的地方
- 并集 —— 两个集合中合起来但不包括一样的
Hash (哈希)
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
哈希基础操作
跟string类型差不多,只不过开头加了个h,添加和删除都是键值对,删一个就都删了
hlen 获取hash表中的字段鼠标
光查看的因为是键值对,所以不好看,直接用hlen查字段数量就可以了
hmest批量创建hash表的字段
hexists 判断hash中指定字段是否存在
hkeys/hvals 获取所有key或者value
incr/decr
分布式锁中用
小结
Zset (有序集合)
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
zadd 在有序集合中添加值
排序
zrem 移除有序集合中的指定元素
zcount 获取指定区间的成员数量
小结
Redis.config配置文件详解
启动的时候需要通过配置文件来启动
redis-server **(配置文件的路径)
网络 NETWOKR
绑定ip如果要让所有ip都可以访问就改成*号,通配符就可以了
访问远程ip的时候改动,默认都是只能是本地访问
通用 GENERAL
一般只需要吧这个守护进程方式改为yes就可以了,支持后台运行
快照 SNAPSHOT
持久化,在规定的时间内执行了多少次操作,则会持久化到aof或者rdb文件中
redis是内存数据库,如果没有数据持久化,那么数据断电即失
主从复制 REPLICATION
安全 SECURITY
可以设置密码,默认是没有密码
客户端 CLIENTS
默认不用管,一般达不到1w个客户端
内存达到上限以后处理策略一般是删除即将过期的key或者永不过期,返回一条错误信息
AOF 配置 APPEND ONLY模式
默认是不开启AOF的,大部分情况下rdb完全够用
sync(同步)
持久化
redis是内存数据库,如果不将内存中的数据库状态保存到磁盘,一旦服务器进程退出,服务器中的数据库状态也会消失,所以Redis提供了持久化功能。
RDB (Redis databases)
在指定的时间间隔内将内存中的数据集体快照写入磁盘中,也就是快照,回复的时候将快照文件读到内存中
Redis会单独创建一个(fork)子进程,会将数据写入到一个临时文件中(rdb),做持久化操作,持久化完了再用这个临时文件替换上次持久化好的文件,整个过程中主进程是不需要进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能会丢失,我们默认使用的rdb,一般情况不修改配置。
rdb保存的是dump.rdb 文件
有时候在生产环境会将rdb文件备份
触发机制
- save的规则满足的情况下,会自动触发rdb规则
- 执行flushall命令,也会触发rdb规则
- 退出redis,也会产生rdb文件
- 备份就自动生成一个dump.rdb文件
如何恢复rdb文件
只需要将rdb文件放到redis启动目录下,redis启动的时候会自动检查dump.rdb恢复其中的数据
查看需要存在的位置
RDB优缺点
优点:
- 适合大规模数据恢复
- 对数据的完整性要求不高,比如59秒没到60秒然后宕机了,这59秒的数据就没了
缺点:
- 需要一定的时间间隔进行操作,如果redis 意外宕机,这个最后一次修改数据就没有了。
- fork进程的时候,会占用一定的内存空间
AOF (Append Only File)
将我们的所有命令都记录下来,history,恢复的时候把这个文件全部执行一遍
以日志的形式 记录每个写操作 将redis执行过的所有指令记录下来(不包括读操作),只许追加文件不允许改写文件,redis启动的时候会读取该文件重新构建数据, 万一是大数据的情况需要写很久,会特别特别慢,效率比较低,redis重启会根据日志内容从前到后执行一遍以完成数据的恢复工作。
AOF保存的是 appendonly.aof 文件
如果开启了aof然后启动redis出错的话,可以检查一下aof文件
重写规则
aof默认的是文件无线追加,文件会越来越大
如果aof文件大于64MB,太大了,就会fork一个新的进程来将我们的文件重写
AOF优缺点
优点:
- 每一次修改都同步,文件的完整性就更好
- 每秒同步一次,可能会丢失一秒的数据
- 从不同步,效率最高
缺点:
- 相对于数据文件来说,aof文件大小远远大于rdb文件,所以修复速度也比rdb文件慢好多
- aof运行效率也比rdb慢,所以默认是使用rdb持久化
持久化扩展
Redis发布订阅
- Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息,微信、微博、关注系统等
- Redis客户端可以订阅任意数量的频道
订阅/发布消息图
第一个 :消息发送者 第二个:频道 第三个:消息订阅者
命令
测试
Redis主从复制
概念
主从复制的作用主要包括:
- 1、数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 2、故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复,实际上是一种服务上的冗余
- 3、负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,从节点提供读服务(即写redis数据时,应用连接主节点;读redis数据时,应用连接从节点),分担服务器负载,尤其是在写少读多的情况下,通过多个读节点分担读负载,可以大大提高redis服务器的并发量。
- 4、高可用(集群)基石:主从复制还是哨兵和集群能够实施的基础,因此主从复制是redis高可用的基石
主从复制,读写分离!80%的情况下都是在进行读操作!减缓服务器的压力!架构中经常使用!一主二从!
只要在公司中,主从复制就是必须要使用的,因为在真实项目中不可能使用单机redis!
环境配置
只配置从库,不配置主库
127.0.0.1:6379> info replication #查看当前库信息
# Replication
role:master #角色:master
connected_slaves:0 #没有从机,0
master_failover_state:no-failover
master_replid:4600a0b169a57f5f23815197e60b9f5fc249b222
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
复制三个配置文件,然后修改对应的信息
- 端口
- pid名字
- log文件名字
- dump.rdb名字
记住先把之前的redis服务关闭,要不然端口会冲突
修改完毕启动三个redis服务,然后通过进程查看
配置文件修改好以后ls会出现那几个redis的log文件
[root@redis-master myconfig]# cp redis.conf redis79.conf
[root@redis-master myconfig]# cp redis.conf redis80.conf
[root@redis-master myconfig]# cp redis.conf redis81.conf
[root@redis-master myconfig]# vim redis69.conf
[root@redis-master myconfig]# vim redis80.conf
[root@redis-master myconfig]# vim redis81.conf
[root@redis-master myconfig]# redis-server redis79.conf
[root@redis-master myconfig]# ls
6379.log redis79.conf redis80.conf redis81.conf redis.conf
[root@redis-master myconfig]# redis-server redis80.conf
[root@redis-master myconfig]# redis-server redis81.conf
[root@redis-master myconfig]# ls
6379.log 6380.log 6381.log appendonly.aof redis79.conf redis80.conf redis81.conf redis.conf
[root@redis-master myconfig]# ps -ef |grep redis
root 4668 1 0 03:00 ? 00:00:12 redis-server 127.0.0.1:6379
root 4836 1 0 03:57 ? 00:00:00 redis-server 127.0.0.1:6380
root 4842 1 0 03:57 ? 00:00:00 redis-server 127.0.0.1:6381
root 4849 4768 0 03:57 pts/2 00:00:00 grep --color=auto redis
一主二从
默认情况下,每台redis服务器都是主节点,一般情况下只需要配置从机
找master 主(79)从(80、81)
slaveof 命令行配置主从
*命令行配置不是永久性的,断开就会失效
slaveof <master的IP> <master的PORT>
[root@redis-master myconfig]# redis-cli -p 6380
127.0.0.1:6380> info replication
# Replication
role:master # 当前角色是master
connected_slaves:0
master_failover_state:no-failover
master_replid:d6fdb6e0430812404571910f8e77ad37467a7652
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:6380> SLAVEOF 127.0.0.1 6379 #设置自己的master主节点,写master的端口号
OK
127.0.0.1:6380> info replication
# Replication
role:slave #角色是slave 从机
master_host:127.0.0.1 #可以看到主机信息
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:1f0c1d2f3ec60e8b2a389e4d7c7e68dfce03ef9c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_hist
80 这样81也是一样
然后再79上查看,从节点有两个
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 #80机器
OK
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379 #81机器
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=168,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=168,lag=1
master_failover_state:no-failover
master_replid:1f0c1d2f3ec60e8b2a389e4d7c7e68dfce03ef9c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:168
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:168
配置文件配置主从
只需要把#号去掉填写master的ip和端口号即可
第二个有密码的认证一下密码即可
细节
主机可以写,从机不能写只能读,主机中的所有信息和数据都会自动被从机保存!
主机写:写name的值为v1 并 查看所有键
从机:可以读到name这个key但是不能写,会报错,只能读取内容
测试:主机断开连接,从机依旧连接主机,但是没有写操作,这个时候主机回来了,从机依旧可以获取到主机写的信息。
如果使用的是命令行来配置的从机,如果重启了就会从从机(slave)变回主机(master)!只要变回从机,就可以立马获取值
复制原理
slaveof 取消主从
slaveof no one 自己当master
哨兵模式
能够后台监控主机是否故障,如果故障根据投票数自动将从库转为主库。
哨兵模式是一种特殊的模式,首先redis提供了哨兵的命令,哨兵是一个独立的进程,他会独立运行,其原理是哨兵通过发送命令,等待redis服务器响应,从而监控运行的多个redis实例
测试
目前状态是一主二从
1、配置哨兵配置文件 sentinel.conf
[root@redis-master myconfig]# vim sentinel.conf
#sentinel monitor 被监控的名称 master的IP 端口号 1
sentinel monitor myredis 127.0.0.1 6379 1
后面这数字 1 代表主机挂了,slave投票(选举)看让谁接替成为主机,票数最多的就会成为主机
2、启动哨兵
[root@redis-master bin]# redis-sentinel myconfig/sentinel.conf
5005:X 16 Jul 2021 06:06:02.545 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5005:X 16 Jul 2021 06:06:02.545 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=5005, just started
5005:X 16 Jul 2021 06:06:02.545 # Configuration loaded
5005:X 16 Jul 2021 06:06:02.545 * Increased maximum number of open files to 10032 (it was originally set to 1024).
5005:X 16 Jul 2021 06:06:02.545 * monotonic clock: POSIX clock_gettime
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.2.4 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 5005
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | https://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
5005:X 16 Jul 2021 06:06:02.546 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
5005:X 16 Jul 2021 06:06:02.549 # Sentinel ID is 345dc7d1a5f83c034cdcef5630b87f7d9d7743d5
5005:X 16 Jul 2021 06:06:02.549 # +monitor master myredis 127.0.0.1 6379 quorum 1
5005:X 16 Jul 2021 06:06:02.551 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
5005:X 16 Jul 2021 06:06:02.553 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
哨兵日志
如果master挂掉了,哨兵就会在从机中选举出一个新的master来代替
第一个failover故障转移
第二个sdown确认6379真的挂了就转移到6381上当master
如果之前的master 6379回来了,就会自动转换成从机(slave)
哨兵模式优缺点
优点:
- 哨兵集群,基于主从复制下,所有的主从配置优点他都有。
- 主从可以切换,鼓掌可以转移,系统的可用性会更好。
- 哨兵模式就是主从模式的升级,手动到自动
缺点:
- redis不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦
- 实现哨兵模式配置比较麻烦,里面配置选项比较多
哨兵模式全部配置
1、一般主要配置这块
2、
3、可以写一些脚本来通知管理员发送一些邮件
4、如果主节点崩了,运维人员不知道就会去通知
redis的缓存穿透与雪崩
服务器的高可用
缓存穿透(查不到)
概念
解决方案
布隆过滤器
缓存空对象
缓存击穿(量太大,缓存过期)
微博服务器打宕机(60s 60.1s 0.1s==> 这0.1秒redis宕机了所有访问全砸到了数据库服务器上)
概述
解决方案
缓存雪崩
概念
双十一会停掉一些服务:比如退款,订单查询这种(保证主要的服务可用)