版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/njys1/article/details/82795876
- get & set
- list
- hash
- set
- sorted set
- HyperLogLog
- geo对象
- 键管理
- 疑问
get & set
redis里最常用的命令了 set {{key}} {{val}} | get {{key}}
注意一些小问题:
set 已存在的键、会将原值覆盖、若不想被覆盖、可以使用setnx
mset & mget 可以一次获取或者设置多个值
eg. mset key val [key2 val2 ...]
mget key1 key2 ...
使用mset 和 mget可以一次执行多个命令、节省网络开销
在redis的内部、使用 int、embstr 和 raw 三种方式来存储字符串对象
eg. 可以使用64位有符号整数表示的字符串会是int编码
长度<=44字节的字符串会是embstr编码
然后、就是raw的编码了
测测看:
127.0.0.1:63790> set key1 12345
OK
127.0.0.1:63790> object encoding key1
"int"
127.0.0.1:63790> set key1 'a'
OK
127.0.0.1:63790> object encoding key1
"embstr"
127.0.0.1:63790> set key3 'I am a long string, not trust, you see~ and my encoding is raw.'
OK
127.0.0.1:63790> object encoding key3
"raw"
list
lpush | rpush 从左端or右端插入
lpop | rpop 从左端or右端删除
lindex key {{index}} 返回key的第index个元素
linsert key before/after val new 在val之前或者之后插入new元素
lrange key start stop 查看key的从start到stop处的元素
notice. lrange mylist 0 -1 可以查找所有的元素
lpushx | rpushx 在列表存在时才会插入
ltrim list start stop 删除start-stop之间的元素
列表是怎么编码呢 ?
127.0.0.1:63790> lrange mylist 0 -1
1) "c"
2) "b"
3) "x"
4) "a"
127.0.0.1:63790> object encoding mylist
"quicklist"
127.0.0.1:63790>
hash
hmset 设置多个属性
hmget 获取多个属性
hexists 测试属性是否存在
hgetall 获取所有属性
在hash变为空时、redis负责删除
hsetnx | hmsetnx 只有key不存在时才设置
hscan key cursor [match pattern] [count number] --[count默认10]
hash最多可以容纳2^32-1个字段、若一个hash的字段很多、hgetall可能会阻塞redis服务器
此时、可以使用hscan来增量获取、每次会返回一个游标、当游标为0时、整个遍历完成
为了方便测试编码、先修改下配置
hash-max-ziplist-entries 20(默认512)
hash-max-ziplist-value 4(默认64)
127.0.0.1:63790> hmset test k1 val1 k2 v2
OK
127.0.0.1:63790> hgetall test
1) "k1"
2) "val1"
3) "k2"
4) "v2"
127.0.0.1:63790> object encoding test
"ziplist"
127.0.0.1:63790> hmset t k1 val1 k2 v3wewe
OK
127.0.0.1:63790> hgetall t
1) "k1"
2) "val1"
3) "k2"
4) "v3wewe"
127.0.0.1:63790> object encoding t
"hashtable"
127.0.0.1:63790>
127.0.0.1:63790> hmset test2 k1 val1 k2wewe v3
OK
127.0.0.1:63790> object encoding test2
"hashtable"
可以看到、当有一个值或者key的长度大于 hash-max-ziplist-value时、就会采用hashtable来实现编码
ziplist对于较小的hash而言可以节省空间
set
sadd 添加元素
sismember 测试是否为集合中的元素
srem 从集合中移除元素
scard 获取集合中元素数量
smembers 获取集合中所有元素、与hgetall一样会阻塞服务器、推荐sscan与hscan用法一致
一个集合最多可容纳 2^23-1个元素
集合计算
sunion sunionstore 计算并集
sinter sinterstore 计算交集
sdiff sdiffstore 计算差集
store结尾的命令可以将结果存储
so、我们关心的存储呢 ? redis怎么设计?
intset 和 hashtable
对于元素都是整数、并且元素个数小于配置 set-max-intset-entries 选项值时、采用intset
sorted set
zadd 向有序集合添加元素
zrevrange 获取元素
zincby 将有序集合中的某个元素socre增加
zscore 获取某个元素的score值
zunionstore 合并zset集合 weights可以设置权重
zadd的nx选项可以只在无元素时进行添加、有元素不更新
长度小于 zset-max-ziplist-entries(默认128) 选项配置的值、并且每个元素的大小都在 zset-max-ziplist-value(默认64) 指定的大小范围内时、会采用ziplist
否则会采用skiplist编码
127.0.0.1:63790> zadd key nx 2 a
(integer) 1
127.0.0.1:63790> object encoding key1
"ziplist"
127.0.0.1:63790>
测试暂时修改下、zset-max-ziplist-value 4
127.0.0.1:63790> zadd key nx 2 adada
(integer) 1
127.0.0.1:63790> object encoding key
"skiplist"
127.0.0.1:63790>
enen~~
HyperLogLog
pfadd 添加元素
pfcount 统计元素值的个数
pfmerge 合并元素
HLL的优势在于能够使用固定数量的内存(每个hll类型的key在内存中仅需要占用12kb的内存、却最多可以计算2^64个不同元素的基数)和常数时间复杂度(每个键O(1))进行唯一计数
两种方式存储:
1. 长度小于配置 hll-sparse-max-bytes 选项设置的值(默认3000) 的hll对象、采用稀疏(Sparse)算法、存储效率更高、但是可能会更消耗CPU资源
2. 另外一部分采用 稠密(Dense)算法
geo对象
geoadd 添加坐标点
geopos 获取坐标点
georadius 查找指定范围内的成员
geodist 获取两个坐标点之间的距离
georadiusbymember 类似georaudius、是由坐标点的成员决定、不是经纬度
eg.
127.0.0.1:63790> geoadd a 20.233 22.233 "x" 20.234 22.234 "y" 20.235 22.235 "z"
(integer) 3
127.0.0.1:63790> georadius a 20.23 22.23 500 m
1) "x"
127.0.0.1:63790> georadiusbymember a x 100 m
1) "x"
可以使用withdist来得到距离
127.0.0.1:63790> georadiusbymember a x 100 m withdist
1) 1) "x"
2) "0.0000"
geo的实现其实是利用zset、所以它可以支持zset的所有命令
键管理
获取所有的键
1) keys*
2) scan
删除key
1) del key
2) unlink key 4.0以上版本引入、用于较大key的异步删除
判断key是否存在
exists key
type查看键的类型
rename对键进行重命名
疑问
1. zcard 和 scard 会先读取元素、再返回元素值 ? 它们比hll对象的劣势在哪里 ?
接下来会去读redis源码分析、再行探索~