前言
这篇文章主要适用于刚开始了解redis的人群,内容比较浅但全。经过整理得到这篇全新的文章。是一篇用于定期观看帮助你加深印象的文章。
Redis
一、什么是Redis?
redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value(高性能键值对的)数据库,并提供多种语言(C、C++、Python、Java、PHP、Ruby、Lua 等)的API。和Memcached类似。redis属于非关系型数据库。
二、Redis支持哪五种数据类型?
1.字符串(strings)
key-value:一个键对应一个值
2.字符串列表(lists)
key-list:一个key对应一个list
3.哈希(hashes)
key-hash:一个key对应map
4.集合(set)
key-set:一个key对应一个set
5.有序集合(zset)
key-zset:一个key对应一个zset
三、Redis架构
redis体系架构主要分为两个部分,分别是redis服务端和redis客户端
四、 Redis持久化
Redis是内存数据库,宕机后数据会消失,Redis重启后才会快速恢复数据,所以要提供持久化机制。
五、Redis的两种持久化方式:RDB和AOF(AOF会记录过程,RDB只管结果)
RDB(Redis DataBase)是Redis默认的存储方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中。它保存的是某一时刻的数据并不关注过程,它主要通过配置文件中的save参数来定义快照的周期。记录Redis数据库的所有键值对。
RDB流程:
1、先设置触发机制
2、触发后将数据以二进制保存起来
3、重启redis自动读取二进制文件
RDB的优缺点
优点:
1.RDB是二进制压缩文件,占用空间小,便于传输(传给slaver);
2.使用RDB文件来恢复数据较快。缺点:不保证数据完整性,会丢失最后一次快照以后更改的所有数据
AOF(Append Only File),开启AOF持久化后Redis将执行的每次写命令以及参数记录到AOF文件中,以此来达到记录数据库状态的目的。这样当重启Redis后只要按顺序回放这些命令就会恢复原始数据了。Redis默认情况下是不开启的,当两种方式同时开启时数据恢复Redis会优先选择AOF恢复。
1、appendfsync always:写操作执行立刻保存
2、appendfsync everysec:每秒
3、appendfsync no:定时
AOF的优缺点
优点:保存的数据额更加完整。安全
缺点:相同的数据集,AOF文件体积大于RDB文件。数据恢复也比较慢。
六、 Redis缓存穿透、缓存击穿、缓存雪崩
三者的含义?
1、缓存穿透:大量请求根本不存在的key
(用户大量请求redis里没有的数据,那么这些请求就得不到redis的响应,redis的命令率下降,这样请求就会直接打在数据库上。导致数据库压力过大从而卡死或宕机)
2、缓存击穿:redis中存在着一个热点key,而这个热点key已经过期了,但是有大量用户访问这一热点key。
(redis的这个热点key过期了,那么这时候大量高并发对于该key的请求就得不到redis的响应,那么就会将请求直接打在数据库上,导致整个数据库瘫痪)
3、缓存雪崩:redis中大量的key集体过期
(当redis中的大量key集体过期,相当于redis中的大部分数据都失效了,那么这时候如果有大量并发的请求来到,那么redis就无法进行有效的响应,请求就都打到数据库上了,数据库崩溃)
根本原因?
redis的命令率下降,这样请求就会直接打在数据库上。导致数据库压力过大从而卡死或宕机
解决方案
缓存穿透解决方案:
1、将数据库id最大值保存进redis中
2、设置黑名单
3、使用布隆过滤器:将可以访问到的资源放入到布隆过滤器中,当一个请求来临的时候先进行布隆过滤器的判断,如果有这个资源则放行,没有直接拦截。
缓存击穿解决方案:
1、对一些热点数据进行设置,可以将他们提前设置在redis中
2、监控哪些数据是热点数据,然后进行对key的过期时长进行调整3、只有一个请求可以获取到互斥锁,然后到数据库中将数据查询并返回到Redis,之后所有请求就可以从Redis中得到响应
缓存雪崩解决方案:
1、设置生存时间用随机数
2、 使用多级架构(nginx缓存+redis缓存+其他缓存,不同层使用不同的缓存,可靠性更强)
3、使用锁或者队列的方式
如果查不到就加上排它锁,其他请求只能进行等待
七、 Redis在linux系统上的相关命令
key-value
k为键,v为值
1、添加 set k v
2、取值 get k
3、批量添加 mset k v k v .....
4、批量取出 mget k k k ....
5、自增 incr k
6、自减 decr k
7、添加数据并设置生存时间
setex k 时间(秒)v
8、指定数量加减
incrby k 值
decrby k 值
9、追加内容
append k v
10、查看值的长度
strlen k
11、添加命令(先判断当前的k在不在,在什么都不做,不在正常添加)
setnx k v
key-hash (m为集合名字 k为键 v为值)
1、添加 hset m k v
2、取出 hget m k
3、批量操作
hmset m k v k v ...
hmget m k k k ...
4、自增 hincrby m k v(具体的数值)
5、添加 ( k都不存在才可以添加)
hsetnx m k v
6、检查
hexits m k
7、删除 hdel m k ....
8、获取所有的键和值
hgetall m
9、获取当前所有的键
hkeys m
10、获取当前键值的数量
hlen m
key - list ( k为列表名 v为值)
1、添加命令
(左插法)lpush k v1、v2、v3 出现顺序为v3、v2、v1
(右插法)rpush k v1、v2、v3 出现顺序为v1、v2、v3
2、如果k存在则添加,反之则什么都不做
(左插法 lpushx k v1、v2、v3
(右插法) rpushx k v1、v2、v3
3、获取数据(弹栈)
(左弹栈)通过 lpop命令移除位于列表最左端的元素,并将被移除的元素返回给用户
lpop k
(右弹栈)通过 rpop 命令移除位于列表最右端的元素,并将被移除的元素返回给用户
rpop k
4、获取指定范围的元素
k为列表名 start为起始元素的下标 stop为终止元素的下标
0表示列表第一个元素,1表示列表第二个元素,以此类推
-1表示列表最后一个元素,-2表示列表第二个元素,以此类推
lrange k start stop
例如:lrange k 0 4
即是查询五个元素 0、1、2、3、4
5、获取指定位置的元素 index索引下标
lindex k index
例子:lindex list1 1
获取list1列表的第二个元素
6、获取整个list长度
llen key
7、删除 k为list名 count数字代表删除的数量 value为值
count代表删除数量 count为正数代表从左边删除,count为负数代表从右边删除
count不写数值默认为1
因为value可以重复所以count可以指定删除几个
lrem k count value
8、保留指定范围的元素
ltrim k start stop
9、将一个列表中最后一个数据插入到另一个列表的头部位置(k1为第一个列表,k2是第二个)
rpoplpush k1 k2
key~set(k为集合名 value为值)
1、添加(不重复且无序)
sadd k value
2、获取全部
smembers k
3、随机获取(删除)
count为数量,不写count默认随机删除一个
spop k count
4、交集(取k1、k2两个集合的交集)
sinter k1 k2
5、并集(取两个集合的并集,重复元素合为一个)
sunion k1 k2
6、差集
k1与k2相比取差值,但只返回k1中的元素
sdiff k1 k2
7、删除
srem k value....
8、判断是否包含 返回结果0代表不包含,1代表包含
sismember k value
key~zset(用于积分、排行榜) value为值 key为集合名字
1、添加
zadd key 分数 value
2、增加分数
zincrby key 分数 值
3、查看分数
zscore key 值
4、查看值的数量
zcard k
5、根据分数范围返回值
zcount key min max
6、删除
zrem key 值
7、根据从小到大的值排序
zrange key start stop withscores
8、根据分数从大到小排序
zrevrange key start stop withscores
9、根据分数返回对应的值
zrangebyscore key min max 【limit offset count】 withscores
+inf代表最大值
-inf代表最小值
key命令(什么都有)
1、有条件的查key
keys z* 表示查看z开头的key
2、查看key在不在
exists key
3、删除
del key......
4、设置key的生存时间
expire key 秒
pexpire key 毫秒
5、设置生存到哪一时间
expireat key 秒
pexpireat key 毫秒
6、查看剩余时间
ttl key 秒
pttl key 毫秒
7、移除生存时间 返回结果1代表成功 0代表失败
persist key
8、换库
select 0~15
9、将一个key移到另一个库中
move key 0~15
10、清空库
flushdp
11、清空所有库
flushall
12、查看所有的库中的key
dbsize
13、查看最后修改时间
lastsave
14、监控
monitor 停监测ctrl c
八、Redis主从复制
主从复制(redis提供的横向扩展机制)
主从复制说白了就是加服务器,一台顶不住就两台,两台顶不住就三台,以此类推。
主从复制肯定就有主从关系。有主服务器和从服务器,其中主服务器主要负责增删改操作,从服务器用于查操作。主服务器所存的数据会自动同步到从服务器中。
写操作找主服务器,读操作找从服务器。
注意:一个主服务器有多个从服务器,但一个从服务器只有一个主服务器。
优点:提高并发能力、分摊并发压力。
缺点:主服务器崩了,从服务器也会崩溃
前面说到主服务器崩了从服务器也会失效。所以redis又给我们提供了哨兵机制。
九、哨兵机制
哨兵机制(提高高可用)
(监视主服务器)当主服务器崩了,选择一个从服务器作为主服务器 。注意的是如果主服务器崩了之后又活了会变为从服务器不会挤主服务器。
哨兵模式怎样在从服务器中选择一个作为主服务器?
投票模式 随机 自己可以给自己投(2n+1 票数在半数以上)
十、Redis集群
Redis集群:Redis的集群实现了数据的分布式存储,对数据进行分片,将不同的数据存储在不同的master节点上面,从而解决了海量数据的存储问题。
Redis集群的特点:
1、没有中心话(没有主从之分)
2、乒乓机制
一问一答
甲~乙 甲~丙 乙~丙
3、投票机制(半数以上)
举个例子:甲给乙发送请求,丙也给乙发送请求,但是乙都没有收到
为何投票,因为甲和丙很有可能自己崩了没有给乙发送出去
这个时候就要投票来判断到底是那个节点崩了
最终投票,判断乙是否死亡
4、所有节点共同管理16284个哈希槽
Redis集群引入了哈希槽的概念
Redis集群有16384个哈希槽(16384)
集群的每个节点负责一部分哈希槽
每个Key通过CRC16算法校验后对16384取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作,方便快捷。
十一、 Redis的淘汰机制
在Redis内存已经满的时候,添加了一个新的数据,执行淘汰机制
volatile-lru:在内存不足时,Redis会再设置过了生存时间的key中干掉一个最少使用的key。
allkeys-lru:在内存不足时,Redis会再全部的key中干掉一个最近最少使用的key。
volatile-lfu:在内存不足时,Redis会再设置过了生存时间的key中干掉一个最近最少频次使用的key。
allkeys-lfu:在内存不足时,Redis会再全部的key中干掉一个最近最少频次使用的key。
volatile-random:在内存不足时,Redis会再设置过了生存时间的key中随机干掉一个。
allkeys-random:在内存不足时,Redis会再全部的key中随机干掉一个。
volatile-ttl:在内存不足时,Redis会再设置过来生存时间的key中干掉一个剩余生存时间最少的key。
noeviction:(默认)在内存不足时,直接报错。