Redis 实战案例总结
Redis 基础Redis的n种妙用,不仅仅是缓存redis实现存取json格式对象/集合数据多线程实现项目初始化完成大规模数据写入redis缓存redis 集群配置实现16个Redis常见使用场景总结Redis 实战篇:巧用数据类型实现亿级数据统计...
目录
Redis原理
Redis实用场景
点赞模块设计 - Redis缓存 + 定时写入数据库实现高性能点赞功能
缓存与数据库一致性
集群配置
Redis 数据类型:
字符串类型 String
1.存储:
set key value time
2.查询:
get key
3.删除:
del key
4.递增或递减:
递增语法:incr key
递增语法(指定步长):incrby key step
递减语法:decr key
递减语法(指定步长):decrby key step
5.追加内容
set ideal hello
OK
append ideal ,ideal-20 # 追加内容
(integer) 14
get ideal
"hello,ideal-20"
6.截取部分字符串:
> get ideal
"hello,ideal-20"
> getrange ideal 0 3
"hell"
> getrange ideal 0 -1
"hello,ideal-20"
(7) 替换部分字符串
语法:setrange key start
> get ideal
"hello,ideal-20"
> setrange ideal 6 bwh # 从下标为6的位置开始替换
(integer) 14
> get ideal
"hello,bwhal-20"
(8) 获取值的长度
语法:strlen key
> strlen addr1
(integer) 7
(9) 不存在的时候才设置
语法:setnx key value
不存在,则创建
存在,则失败
> setnx address guangdong # address键 不存在,则创建
(integer) 1
> get address
"guangdong"
> setnx address beijing # address键 存在,则失败
(integer) 0
> get address
"guangdong"
(10) 同时存储获取多个值
同时存储多个值:mset key1 value1 key2 value2 …
同时获取多个值:mget key1 key2
同时存储多个值(保证不存在):msetnx key1 value1 key2 value2 …
此操作为原子性操作,要失败全部失败
> mset addr1 beijing addr2 guangdong addr3 shanghai # 同时存储多个值
OK
> keys *
1) "addr3"
2) "addr2"
3) "addr1"
> mget addr1 addr2 addr3 # 同时获取多个值
1) "beijing"
2) "guangdong"
3) "shanghai"
> msetnx age1 20 age2 25 age3 30 # 第一次同时存储多个值(保证不存在)
(integer) 1
> msetnx age4 35 age5 40 age1 45 # 第二次同时存储多个值(保证不存在),失败了
(integer) 0
>
(11) 设置对象
语法:key value (key 例如:user:1 ,value为一个json字符串)
> set user:1 {name:zhangsan,age:20} # 存一个对象
OK
> keys *
1) "user:1"
> get user:1
"{name:zhangsan,age:20}"
以上这种 user:1 的设计在 Redis 中是允许的,例子如下
语法:对象名:{id}:{filed}
> mset user:1:name lisi user:1:age 25
OK
> mget user:1:name user:1:age
1) "lisi"
2) "25"
(12) 先 get 后 set
语法:getset
先取到原来的值,然后再把新值覆盖,如果原先没有值返回 nil
> getset addr beijing # 原先没有值,返回 nil
(nil)
> get addr
"beijing"
> getset addr guangdong # 原先有值,返回原先的值,然后覆盖新值
"beijing"
> get addr
"guangdong"
列表类型 - list
(1) 添加
A:从左或从右添加元素
lpush key value:将元素添加到列表左边
Rpush key value:将元素添加到列表右边
> lpush list1 A
(integer) 1
> lpush list1 B
(integer) 2
> lpush list1 C
(integer) 3
> lrange list1 0 -1
1) "C"
2) "B"
3) "A"
B:插入新值到某个值前后
语法:linsert list before/after value newvalue
> lrange list1 0 -1
1) "A"
2) "B"
3) "C"
> linsert list1 before C XXX # 在 C 前插入 XXX
(integer) 4
> lrange list1 0 -1
1) "A"
2) "B"
3) "XXX"
4) "C"
(2) 获取:
A:根据区间获取值
语法:lrange key start end
> lrange list1 0 -1 # 获取所有值
1) "C"
2) "B"
3) "A"
> lrange list1 0 1 # 获取指定区间的值
1) "C"
2) "B"
B:根据下标获取值
语法:lindex list 下标
> lrange list1 0 -1
1) "C"
2) "B
> lindex list1 0
"C"
> lindex list1 1
"B"
C:获取列表的长度
语法 llen list
> llen list1
(integer) 1
(3) 删除
A:移除最左或最右的元素
lpop key:删除列表最左边的元素,且返回元素
rpop key:删除列表最右边的元素,且返回元素
> lrange list1 0 -1
1) "D"
2) "C"
3) "B"
4) "A"
> lpop list1 # 删除列表最左边的元素,且返回元素
"D"
> rpop list1 # 删除列表最右边的元素,且返回元素
"A"
> lrange list1 0 -1
1) "C"
2) "B"
B:移除指定的值
语法:lrem list num value
> lrange list1 0 -1
1) "C"
2) "C"
3) "B"
4) "A"
> lrem list1 1 A # 删除1个A
(integer) 1
> lrange list1 0 -1
1) "C"
2) "C"
3) "B"
> lrem list1 2 C # 删除2个C
(integer) 2
> lrange list1 0 -1
1) "B"
>
C:移除最后一个元素且添加到另一个list
rpoplpush list1 list2
> lrange list1 0 -1
1) "A"
2) "B"
3) "C"
> rpoplpush list1 list2 # 移除 list1 中最后一个元素,且添加到list2 中去
"C"
> lrange list1 0 -1
1) "A"
2) "B"
> lrange list2 0 -1
1) "C"
(4) 根据下标范围截取 list
语法:ltrim list start end
> rpush list1 A
(integer) 1
> rpush list1 B
(integer) 2
> rpush list1 C
(integer) 3
> rpush list1 D
(integer) 4
> ltrim list1 1 2 # 截取下标为1到2的值
OK
> lrange list1 0 -1
1) "B"
2) "C"
(5) 替换指定下标的值
语法:lset list 下标 value
> exists list1 # 判断是否存在此list
(integer) 0
> lset list1 0 beijing # 不存在,替换报错
(error) ERR no such key
> lpush list1 guangdong # 创建一个list
(integer) 1
> lindex list1 0
"guangdong"
> lset list1 0 beijing # 存在,替换成功
OK
> lindex list1 0
"beijing"
集合类型 - set
set:一种无序(不保证有序)集合,且元素不能重复
(1) 添加
语法:sadd key value
> sadd set1 A
(integer) 1
> sadd set1 B
(integer) 1
> sadd set1 C
(integer) 1
> sadd set1 C # set的值不能重复
(integer) 0
> smembers set1 # 查询指定set的所有值,乱序
1) "B"
2) "A"
3) "C"
(2) 获取
A:获取set集合中的所有元素
语法:smembers key
> smesmbers set1 # 查询指定set的所有值,乱序
1) "B"
2) "A"
3) "C"
B:获取元素的个数
语法:scard set
> scard set1
(integer) 3
C:随机获取元素
语法:sembers set [num]
默认获取一个随机元素,后跟数字,代表随机获取几个元素
> smembers set1
1) "D"
2) "B"
3) "A"
4) "C"
> srandmember set1 # 获取一个随机元素
"D"
> srandmember set1 # 获取一个随机元素
"B"
> srandmember set1 2 # 获取两个随机元素
1) "A"
2) "D"
(3) 删除
A:删除set集合中某元素
语法:srem key value
> srem set1 C # 删除 C 这个元素
(integer) 1
> smembers set1
1) "B"
2) "A"
B:随机删除一个元素
语法:spop set
> smembers set1
1) "D"
2) "B"
3) "A"
4) "C"
> spop set1 # 随机删除一个元素
"A"
> spop set1 # 随机删除一个元素
"B"
> smembers set1
1) "D"
2) "C"
(4) 移动指定值到另一个set
语法:smove set1 set2 value
> smembers set1
1) "D"
2) "C"
> smove set1 set2 D # 从 set1 移动 D 到 set2
(integer) 1
> smembers set1
1) "C"
> smembers set2
1) "D"
(5) 交集 并集 差集
sinter set1 set2:交集
sunion set1 set2:并集
sdiff set1 set2:差集
> sadd set1 A
(integer) 1
> sadd set1 B
(integer) 1
> sadd set1 C
(integer) 1
> sadd set2 B
(integer) 1
> sadd set2 C
(integer) 1
> sadd set2 D
(integer) 1
> sadd set2 E
(integer) 1
> sinter set1 set2 # 交集
1) "B"
2) "C"
> sunion set1 set2 # 并集
1) "D"
2) "E"
3) "C"
4) "B"
5) "A"
> sdiff set1 set2 # 差集
1) "A"
有序集合类型 - sortedset/zset
此类型和 set 一样也是 string 类型元素的集合,且不允许重复的元素
不同的是每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序
有序集合的成员是唯一,但分数(score)却可以重复
(1) 添加
语法:zadd key score value [score value … …]
> zadd sortedset1 20 zhangsan # 添加一个
(integer) 1
> zadd sortedset1 10 lisi 60 wangwu # 添加多个
(integer) 2
(2) 获取
A:获取所有值(默认排序)
语法:zrange sortedset start end [withscores]
根据那个值的大小进行了排序,例如上面的 10 20 60
> zrange sortedset1 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
B:获取所有值(从小到大和从大到小)
zrangebyscore sortedset -inf +inf:从小到大
zrevrange sortedset 0 -1:从大到小
> zrangebyscore sortedset1 -inf +inf # 从小到大
1) "lisi"
2) "zhangsan"
3) "wangwu"
> zrevrange sortedset1 0 -1 # 从大到小
1) "wangwu"
2) "zhangsan"
3) "lisi"
C:获取值且附带数值
zrangebyscore sortedset -inf +inf withscores:从小到大且附带值
> zrangebyscore sortedset1 -inf +inf withscores # 显示从小到大且附带值
1) "lisi"
2) "10"
3) "zhangsan"
4) "20"
5) "wangwu"
6) "60"
> zrangebyscore sortedset1 -inf 20 withscores # 显示从小到大,且数值小于20的
1) "lisi"
2) "10"
3) "zhangsan"
4) "20"
>
D:获取有序集合中的个数
语法:zcard sortedset
> zcard sortedset1
(integer) 2
E:获取指定区间成员数量
语法:zcount sortedset start end (strat 和 end是指那个数值,而不是什么下标)
> zcount sortedset1 10 60
(integer) 3
(2) 删除
zrem key value
> zrange sortedset1 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
> zrem sortedset1 wangwu # 删除 wangwu 这个元素
(integer) 1
> zrange sortedset1 0 -1
1) "lisi"
2) "zhangsan"
哈希类型 - hash
(1) 添加
A:普通添加
语法:hset hash field value
> hset hash1 username admin
(integer) 1
> hset hash1 password admin
(integer) 1
B:不存在才可以添加
语法:hsetnx hash filed value
> hsetnx hash1 username admin888 # 已存在,失败
(integer) 0
> hsetnx hash1 code 666 # 不存在,成功
(integer) 1
(2) 获取
A:获取指定的field对应的值
语法:hget hash field [ key field … …]
> hget hash1 password
"admin"
B:获取所有的field和value
语法:hgetall hash
> hgetall hash1
1) "username"
2) "admin"
3) "password"
4) "admin"
C:获取 hash 的字段数量
语法:hlen hash
> hlen hash1
(integer) 2
D:只获取所有 field 或 value
hkeys hash:获取所有 field 字段
hvals hash:获取所有 value 值
> hkeys hash1 # 获取所有 field 字段
1) "username"
2) "password"
> hvals hash1 # 获取所有 value 值
1) "admin"
2) "admin"
(3) 删除
语法:hdel hash field
> hdel hash1 username
(integer) 1
(4) 自增自减
hincrby hash field 增量
> hsetnx hash1 code 666
(integer) 1
> hincrby hash1 code 2
(integer) 668
> hincrby hash1 code -68
(integer) 600
三种特殊数据类型
Geospatial(地理位置)
使用经纬度,作为地理坐标,然后存储到一个有序集合 zset/sortedset 中去保存,所以 zset 中的命令也是可以使用的
特别是需要删除一个位置时,没有GEODEL命令,是因为你可以用ZREM来删除一个元素(其结构就是一个有序结构)
Geospatial 这个类型可以用来实现存储城市坐标,一般都不是自己录入,因为城市数据都是固定的,所以都是通过 Java 直接导入的,下面都是一些例子而已
Geospatial 还可以用来实现附近的人这种概念,每一个位置就是人当前的经纬度,还有一些能够测量距离等等的方法,后面都会提到
命令列表:
(1) 存储经纬度
语法:geoadd key longitud latitude member […]
longitud——经度、 latitude——纬度
有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。
> geoadd china:city 116.413384 39.910925 beijing
(integer) 1
> geoadd china:city 113.271431 23.135336 guangzhou
(integer) 1
> geoadd china:city 113.582555 22.276565 zhuhai
(integer) 1
> geoadd china:city 112.556391 37.876989 taiyuan
(integer) 1
(2) 获取集合中一个或者多个成员的坐标
语法:geopos key member [member…]
> geopos china:city beijing zhuhai
1) 1) "116.41338318586349487"
2) "39.9109247398676743"
2) 1) "116.41338318586349487"
2) "39.9109247398676743"
(3) 返回两个给定位置之间的距离
语法:geodist key member1 member2 [unit]
单位默认为米,可以修改,跟在 member 后即可,例如 km
指定单位的参数 unit 必须是以下单位的其中一个:
m 表示单位为米
km 表示单位为千米
mi 表示单位为英里
ft 表示单位为英尺
> geodist china:city guangzhou taiyuan
"1641074.3783"
> geodist china:city guangzhou taiyuan km
"1641.0744"
(4) 查找附近的元素(给定经纬度和长度)
含义:以给定的经纬度为中心, 返回集合包含的位置元素当中
语法:georadius key longitude latitude radius m|km|mi|ft [WITHCOORD][WITHDIST] [WITHHASH] [COUNT count]
与中心的距离不超过给定最大距离的所有位置元素
通过georadius就可以完成 附近的人功能(例如这个位置我们输入的是人当前的位置)
withcoord:带上坐标
withdist:带上距离,单位与半径单位相同
count :只显示前n个(按距离递增排序)
> georadius china:city 113.582555 22.276565 500 km
1) "zhuhai"
2) "guangzhou"
> georadius china:city 113.582555 22.276565 500 km withdist withcoord count 1
1) 1) "zhuhai"
2) "0.0002"
3) 1) "113.58255296945571899"
2) "22.27656546780746538"
> georadius china:city 113.582555 22.276565 500 km withdist withcoord count 2
1) 1) "zhuhai"
2) "0.0002"
3) 1) "113.58255296945571899"
2) "22.27656546780746538"
2) 1) "guangzhou"
2) "100.7111"
3) 1) "113.27143281698226929"
2) "23.13533660075498233"
(5) 查找附近的元素(指定已有成员和长度)
含义:5 与 4 相同,给定的不是经纬度而是集合中的已有成员
语法:GEORADIUSBYMEMBER key member radius…
> georadiusbymember china:city zhuhai 500 km
1) "zhuhai"
2) "guangzhou"
(6) 返回一个或多个位置元素的Geohash表示
语法:geohash key member1 [member2…]
> geohash china:city zhuhai
1) "weby8xk63k0"
Hyperloglog(基数统计)
HyperLogLog 是用来做**基数(数据集中不重复的元素的个数)**统计的算法,其底层使用string数据类型
HyperLogLog 的优点是:
在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的
花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数
因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素
一个常见的例子:
传统实现,存储用户的id,然后每次进行比较。当用户变多之后这种方式及其浪费空间,而我们的目的只是计数,Hyperloglog就能帮助我们利用最小的空间完成。
(1) 添加
含义:添加指定元素到 HyperLogLog 中
语法:PFADD key element1 [elememt2…]
> pfadd test1 A B C D E F G
(integer) 1
> pfadd test2 C C C D E F G
(integer) 1
(2) 估算myelx的基数
含义:返回给定 HyperLogLog 的基数估算值
语法:PFCOUNT key [key]
> pfcount test1
(integer) 7
> pfcount test2
(integer) 5
(3) 合并
含义:将多个 HyperLogLog 合并为一个 HyperLogLog
语法:PFMERGE destkey sourcekey [sourcekey…]
> pfmerge test test1 test2
OK
> pfcount test
(integer) 9
BitMaps(位图)
BitMaps 使用位存储,信息状态只有 0 和 1
Bitma p是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR,NOT以及其它位操作
这种类型的应用场景很多,例如统计员工是否打卡,或者登陆未登录,活跃不活跃,都可以考虑使用此类型
(1) 设置值
含义:为指定key的offset位设置值
语法:setbit key offset value
> setbit sign 0 1
(integer) 0
> setbit sign 1 0
(integer) 0
> setbit sign 2 0
(integer) 0
> setbit sign 3 0
(integer) 0
> setbit sign 4 1
(integer) 0
> setbit sign 5 1
(integer) 0
> setbit sign 6 1
(integer) 0
(2) 获取
含义:获取offset位的值
语法:getbit key offset
> getbit sign 4
(integer) 1
> getbit sign 2
(integer) 0
(3) 统计
含义:统计字符串被设置为1的bit数,也可以指定统计范围按字节
语法:bitcount key [start end]
> bitcount sign
(integer) 4
批量删除
scan 0 match keys* count 10000
DEL 123456
更多推荐
所有评论(0)