目录
redis五大基本数据类型
基础命令
flushall #清空所有数据库
flushdb #清空当前数据库
keys * #查看所有的key
exists name #判断当前的key是否存在
move name #移除key
expire name 10 #给name设置过期时间10秒
pexpire name 10 #给name设置过期时间10毫秒
persist name #取消过期
ttl name #查看name还有多久过期为负数时已过期
type name #查看name的类型
string
get key #获取key的值
set key v #设置key的值
del key #删除key(应用于所有类型)
incr key #将储存的值加上1
decr key #将储存的值减去1
incrby key amout #加上整数amount
decrby key amout #减去整数amount
incrbyfloat key amout #加上浮点数amount字符串二进制
append key v #将值追加到key当前储存值的末尾
strlen key #获取字符串长度
getrange key start end #获取下标start到end的字符串
setrange key offset v #将字符串看做二进制位串,并将位串中偏移量为offset的二进制位的值
getbit key offset #将字符串看做是二进制位串值为1的二进制位的数量,如果给定了可选的start偏移 量和end偏移量,那么只对偏移量指定范围的二进制位进行统计
bitop operation dest-key key-name [key-name …] #对一个或多个二进制位串进行 并and,或 or,异或-------XOR,非NOT 在内的任意一种安位运算符操作(bitwise operation),并将计算的结果放到dest -key里面
list
rpush key [v…] #将一个或多个加入列表右端
lpush key [v…] #将一个或多个加入列表左端
rpop key #移除并返回最右端的元素
lpop key #移除并返回列表最左端的元素
lrem key 2 "hello" #移除列表中两个hello
ltrim key 1 -1 #保留下标为1以上的元素
llen key #返回列表的长度
lindex key size #返回下标(偏移量)为size的元素
lrange key start end #返回从start 到end的元素 包含start和end
ltrim key start end #只保留从start 到end的元素 包含start和end
hash
hmget hkey key… #获取多个值
hmset hkey key v… #为多个key设置值
hdel hkey key… #删除多个值并返回
hlen hkey #返回总数量
hexists hkey key #检查key是否存在在散列中
hkeys hkey #获取散列中所有key
hvals hkey #获取三列中所有值
hgetall hkey #获取散列
hincrby hkey key increment #为key的值上加上整数increment
hincrbyfloat hkey key increment #为key的值上加上浮点数increment
set
sadd key item … #添加多个,返回新添加的个数(已存在的不算)
srem key item… #从集合移除多个元素 ,返回被移除元素的数量
sismember key item #检查元素item是否在集合中
scard key #返回集合总数
smembers key #返回所有元素
srandmember key cout #随机返回cout个元素 cout为正整数 随机元素不重复 相反可能会出现重复
spop key #随机的移除一个元素 并返回已删除的元素
smove key1 key2 item #如果key1中包含item 移除key1中的item 添加到key2中,成功返回1 失败返回0
差运算 sdiffstore newkey key key1… #将存在于key集合但是不存在key1…集合的其他元素 放到newkey里面(咬掉一口剩下的)
交运算 sinter key… #返回所有集合的交集(返回我们都有的的)
交运算 sinterstore newkey key… #返回多个集合的交集生成集合newkey
并运算 sunion key… #(返回我们不重复的所有元素 )
并运算 sunion newkey key… #结果放到newkey中
zset
zadd key score member … #添加多个
zerm key memer… #移除多个
zcard key #返回所有成员
zincrby key incremnet member #将member成员的分值加上increment
zcount key min max #返回分值在 min和max中间的排名
zrank key member #返回成员member在集合中的排名
zscore key member #返回member的分值
zrange key start stop #返回 介于两者之间的成员
redis三种特殊数据类型
geospatial 地理位置
底层是zset实现的, 可以用zset的命令操作
geoadd china:city 16.40 39.90 beijing #添加经纬度
geopos china:city beijing #获取指定城市的经度和纬度
geodist china:city chongqing hangzhou km #查看重庆到杭州的直线距离"1318.8910"
最后一个距离单位参数说明:
m :米,默认单位。
km :千米。
mi :英里。
ft :英尺。
georadius china:city 110 30 1000 km #以110 30 这个经纬度为中心 寻找方圆1000km内的城市geohash china:city hangzhou chongqing #将二维的经纬度转换成一维的字符串,如果两个字符串越接近,则距离越近
hyperloglog基数统计
HyperLogLog 是用来做基数统计的算法
基数:比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。
会有一定误差!!
应用场景:
网站统计用户访问量 uv
pfadd mykey a b c d e #添加
pfcount mykey #统计基数数量
pfmerge mykey3 mykey mykey1 #合并多个hyperloglog,将mykey和mykey1合并为mykey3
bitmap
应用场景:
- 统计用户信息 :活跃、不活跃! 登录、未登录! 打卡!
只要是两个状态的,就可以使用bitmaps
bitmaps 都是操作二进制进行位记录
setbit key offset value #value只能是0或1
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0
127.0.0.1:6379> getbit sign 3 #查看某一天是否有打卡
(integer) 1
127.0.0.1:6379> getbit sign 6
(integer) 1
bitcount sign #统计这周的打卡记录
Redis事务
概念
redis单条命令保证原子性,但是事务不保证原子性
redis事务本质:一组命令的集合,一个事务的所有命令都会被序列化,这事务执行过程中,会按照顺序执行
redis事务没有隔离级别概念
事务:
- 开启事务multi
- 命令入队
- 执行事务exec
放弃事务:discard
- multi 开启事务
- exec 提交事务
- discard 取消事务
- watch 监控,如果监控的值发生变化,则提交事务时会失败
- unwatch 去掉监控
如果事务队列存在命令错误,事务其他命令不会执行
如果事务队列中执行时出现异常,其他命令可以正常运行
悲观锁和乐观锁
悲观锁:认为什么时候都会出问题,无论做什么都会加锁
乐观锁:认为什么时候都不会出问题,不会上锁,更新数据的时候去判断一下,此期间时候有人修改过这个数据,获取version,更新的时候比较version
Redis数据持久化的两种模式
简介
Redis中为了保证在系统宕机(类似进程被杀死)情况下,能更快的进行故障恢复,设计了两种数据持久化方案,分别为rdb和aof。
RDB
Rdb方式是通过手动(save-阻塞式或bgsave-异步)或周期性方式保存redis中key/value的一种机制,Rdb方式一般为redis的默认数据持久化方式.
RDB:把当前数据生成快照保存在硬盘上。
过程:
开启方式:修改redis.conf配置文件中的save策略
Aof
Aof方式是通过记录写操作日志的方式,记录redis数据的一种持久化机制,这个机制默认是没有开启的.
AOF:记录每次对数据的操作到硬盘上。
过程:
开启方式:修改redis.conf配置文件中的appendfsync配置持久化策略
appendfsnc属性有三个:
always:将aof_buf缓冲区中的所有内容写入并同步到AOF文件,每次有新命令追加到 AOF 文件时就执行一次
everysec(默认):每一秒追加一次,可能会丢失这一秒的数据。
no:将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统(OS)决定。
优缺点
redis主从复制
主从复制:指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节(Master/Leader),后者称为从节点(Slave/Follower), 数据的复制是单向的!只能由主节点复制到从节点(主节点以写为主、从节点以读为主)。
哨兵模式
介绍
Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态
在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用
作用
- 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
- 提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作。
它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master;
当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。
Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
redis缓存穿透与雪崩
缓存穿透
概念:用户想要查询一个数据,发现redis内存数据库没有,于是向持久层数据库查询,发现也没有,于是查询失败。当用户很多时,缓存都没有命中,于是都去请求持久层数据库,这样会给数据库带来很大的压力,这个时候就相当于出现了缓存穿透
解决方案:
- 利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试。
- 采用异步更新策略,无论 Key 是否取到值,都直接返回。Value 值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
- 提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的 Key。迅速判断出,请求所携带的 Key 是否合法有效。如果不合法,则直接返回。
布隆过滤器
底层是一个二进制数组,插入数据时通过hash运算计算出哈希值,与这个数组的下标进行映射,存在的话就将这个二进制数据修改为1
优点:
- 是一串二进制数组组成的数据,占用空间非常小
- 插入和查询速度比较快,因为它是通过计算hash值运算进行查找数据
- 保密性好,因为存储的都是二进制数据,别人根本不知道它代表的是什么
缺点:
- 删除时会删除掉一些不应该删除的数据,因为进行hash运算时会出现不同的数据hash值相同
- 查询时会出现误判
怎么防止缓存穿透
通过布隆过滤器判断数据库中是否含有这个数据,没有这个数据,就可以不用查询数据库
缓存击穿
概念:热点数据缓存失效,用户大量访问数据库
解决方法
- 设置key永远不过期,或者快过期时,通过另一个异步线程重新设置key
- 当从缓存拿到的数据为null,重新从数据库加载数据的过程上锁,下面写个分布式锁实现的demo
缓存雪崩:大量缓存在同一时间内失效,这个时候来了大量用户,请求全部怼到了数据库上
缓存雪崩
概念:缓存雪崩,即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。
缓存雪崩解决方案:
1. 给缓存的失效时间,加上一个随机值,避免集体失效。
2. 使用互斥锁,但是该方案吞吐量明显下降了。