String(字符串)
-
常用命令
SET key value GET key GETRANGE key start end #返回[start, end]区间的字符串,key不存在时返回空字符串 MGET key1 key2 #按顺序返回所有key的值,key不存在对应值返回null INCR key #返回原key值加1,原key值为数字型字符串 INCRBY key number #返回原key值加number,原key值为数字型字符串 DECR key #返回原key值减1,原key值为数字型字符串 DECRBY key #返回原key值减number,原key值为数字型字符串 APPEND key value #返回key值的长度;若原key值存在则在值后追加组成新值,若不存在则新建key值
-
应用场景
字符串是最常用的数据类型,他能够存储任何类型的字符串,当然也包括二进制、JSON化的对象、甚至是Base64编码之后的图片。在Redis中一个字符串最大的容量为512MB。
-
查看内部编码
object encoding key #key的内部编码
-
字符串的内部编码
- int:8个字节的长整型
- embstr:小于等于 39 个字节的字符串
- raw:大于39个字节的字符串
Hash(哈希)
-
常用命令
HSET key field1 value1 field2 value2 #返回设置的键值对个数 HGETALL key #返回整个哈希表 HEXISTS key field #返回哈希表中是否存在某个field值 HGET key field #返回哈希表field字段对应的值 HKEYS key #返回哈希表中所有字段 HVALS key #返回哈希表中所有字段值 HSET key field1 value1 field2 value2 #设置哈希表中各字段值,不存在则新增,有新增返回新增个数,无则返回0 HMSET key field1 value1 field2 value2 #设置哈希表中各字段值,不存在则新增,返回ok HMGET key field1 field2 #获取哈希表中的多个字段 HLEN key #返回哈希表字段个数 HSETNX key field value #只有在字段 field 不存在时,设置哈希表字段的值,成功返回1,失败0 HINCRBY key field number #number可以为负数意味着减;为field字段的整数值加number,不存field字段则新增,返回新增之后的值 HINCRBYFLOAT key field number #number可以为负数意味着减;为field字段的浮点数加number,不存field字段则新增,返回新增之后的值;也可以为整型数据的field加,值会变成float类型,最好不用这么来处理 HDEL key field1 field2 #删除哈希表中字段,返回删除个数
-
应用场景
每个 hash 可以存储 2^32 - 1 键值对(42亿多), 用于存储对象信息;如果用字符串来保存,需要进行序列化/反序列化,增加开销;并且只需要修改一项的时候,需要把整个对象信息取回,修改的时候还要防止并发操作,增加了复杂性。使用哈希存储则没有这些问题;同时需要注意HGETALL命令可以读取所有属性数据,但是如果内部 Map 的成员很多,那么涉及到遍历整个内部 Map 的操作,由于 Redis 单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意。
-
哈希的内部编码
- ziplist(压缩列表):当哈希类型中元素个数小于 hash-max-ziplist-entries 配置(默认 512 个),同时所有值都小于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使用 ziplist 作为哈希的内部实现。
- hashtable(哈希表):当上述条件不满足时,Redis 则会采用 hashtable 作为哈希的内部实现。
List(列表)
-
常用命令
LPUSH key value1 value2 #将value1 value2插入key的队列的头部 LPUSHX key value1 value2 #将value1 value2插入已存在队列的头部;不存在队列时操作失败返回0,存在队列时,返回目前队列元素的个数 RPUSH key value1 value2 #将value1 value2插入key的队列的尾部 RPUSHX key value1 value2 #将value1 value2插入已存在队列的尾部;不存在队列时操作失败返回0,存在队列时,返回目前队列元素的个数 LRANGE key start end #获取列表指定[start, end]范围内的元素 LLEN key #获取列表元素个数 LINDEX key index #返回队列中index下标的元素 LREM key count value #移除元素,count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT;count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值;count = 0 : 移除表中所有与 VALUE 相等的值。 LTRIM key start end #修剪队列,移除[start, end]之外的所有元素 RPOP key #移除列表的最后一个元素,返回值为移除的元素 LPOP key #移出并获取列表的第一个元素 RPOPLPUSH source_list destination_list #从source_list队尾移除一个元素,并返回,放入destination_list队头 BRPOPLPUSH source_list destination_list timeout #从source_list队尾移除一个元素,并返回,放入destination_list队头;如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 BLPOP key timeout #移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 BRPOP key timeout #移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 LINSERT key BEFORE|AFTER pivote value #从队列头部开始查找首次出现pivote的位置,进行before或者after插入value,并返回队列元素个数 LSET key index value #通过索引设置队列中的元素
-
应用场景
列表(list)用来存储多个有序的字符串,每个字符串称为元素;一个列表可以存储2^32-1(42亿多)个元素。Redis中的列表支持两端插入和弹出,并可以获得指定位置(或范围)的元素,可以充当数组、队列、栈等。比如 twitter 的关注列表,粉丝列表等都可以用 Redis 的 list 结构来实现,可以利用lrange命令,做基于Redis的分页功能,性能极佳,用户体验好
-
列表的内部编码
- ziplist(压缩列表):当列表中元素个数小于 512(默认)个,并且列表中每个元素的值都小于 64(默认)个字节时,Redis 会选择用 ziplist 来作为列表的内部实现以减少内存的使用。当然上述默认值也可以通过相关参数修改:list-max-ziplist-entried(元素个数)、list-max-ziplist-value(元素值)。
- linkedlist(链表):当列表类型无法满足 ziplist 条件时,Redis 会选择用 linkedlist 作为列表的内部实现。
Set(集合)
-
常用命令
SADD key member1 member2 #向集合中添加一个或多个成员,返回添加成功个数,不重复 SCARD key #查看集合成员个数 SDIFF key1 key2 #返回第一个集合与其他集合之间的差 和php的array_diff()相似 SDIFFSTORE destination key1 key2 #第一个集合与其他集合之间的差,并保存在新的集合destination中,返回destination成员个数 SINTER key1 key2 #返回多个集合的交集 和php的array_intersect()相似 SINTERSTORE destination key1 key2 #多个集合的交集,并保存在新的集合destination中,返回destination成员个数 SISMEMBER key member #集合中是否存在member,返回0或者1 SMEMBERS key #返回集合中所有成员 SMOVE source destination member #将source集合中的member移到destination集合中,若destination集合不存在则创建,成功返回1,失败返回0 SPOP key count #从集合key中随机移除count个成员,并返回移除成员数组,当集合为空时,自动删除集合 SRANDMEMBER key count #从集合key中随机返回count个成员,并返回成员数组 SUNION key1 key2 #返回所有给定集合的并集 SUNIONSTORE destination key1 key2 #将所有给定集合的并集,保存在destination集合中,并返回destination集合成员个数
-
应用场景
Redis set 对外提供的功能与 list 类似是一个列表的功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,并且 set 提供了判断某个成员是否在一个 set 集合内的重要接口,这个也是 list 所不能提供的。和list的区别
- set元素不重复,list可以重复
- set无序,list有序
- set无法通过下标获取元素,list可以
- 多个set可以获取交集,并集,差集
-
内部编码
-
intset(整数集合):当集合中的元素都是整数,并且集合中的元素个数小于 512 个时,Redis 会选用 intset 作为底层内部实现。
-
hashtable(哈希表):当上述条件不满足时,Redis 会采用 hashtable 作为底层实现。
注:可以通过set-max-intset-entries设置上述参数
-
Sorted Set(有序集合)
-
常用命令
ZADD key score1 member1 score2 member2 #向有序集合添加一个或多个成员,或者更新已存在成员的分数,返回新增元素个数 ZCARD key #返回有序集合元素个数 ZCOUNT key min max #返回指定分数区间[min, max]的元素个数 ZINCRBY key increment member #给有序集合指定成员的分数加上increment,并返回该成员分数 ZINTERSTORE destination numberkeys key1 key2 #计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 destination 中,numberkeys为所有key的个数,destination结果集中的对应成员分数默认是各个key中成员分数之和,此方式可以用来做各科分数之和统计(每一科代表一个key) ZRANGE key start end [WITHSCORES] #通过索引区间返回有序集合指定区间内的成员 ZLEXCOUNT key min max #返回集合中的在字典区间的个数,注:min max 格式:包含[min [max,不包含(min (max,全部表示为 - + ZRANGEBYLEX key min max [limit offset count] #通过字典区间返回有序集合的成员 ZRANGEBYSCORE key min max [WITHSCORES] [limit] #通过分数返回有序集合指定区间内的成员 ZRANK key member #返回有序集合中指定成员的索引 ZREM key member1 member2 #移除有序集合中的一个或多个成员 ZREMRANGEBYLEX key min max #移除有序集合中给定的字典区间的所有成员 ZREMRANGEBYRANK key start end #移除有序集合中给定的排名区间的所有成员 ZREMRANGEBYSCORE key min max #移除有序集合中给定的分数区间的所有成员 ZREVRANGE key start stop [WITHSCORES] #返回有序集中指定分数区间内的成员,分数从高到低排序 ZREVRANK key member #返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 ZSCORE key member #返回有序集中,成员的分数值 ZUNIONSTORE destination numberkeys key1 key2 #计算给定的一个或多个有序集的并集并将结果集存储在新的有序集合 destination 中,numberkeys为所有key的个数,destination结果集中的对应成员分数默认是各个key中成员分数之和 ZSCAN key cursor [MATCH pattern] [COUNT count] #迭代有序集合中的元素(包括元素成员和元素分值)
-
使用场景
sorted set 可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择 sorted set 数据结构,比如 twitter 的 public timeline 可以以发表时间作为 score 来存储,这样获取时就是自动按时间排好序的。根据点击数做出排行榜。
-
内部编码
- ziplist(压缩列表):当有序集合的元素个数小于 128 个(默认设置),同时每个元素的值都小于 64 字节(默认设置),Redis 会采用 ziplist 作为有序集合的内部实现。
- skiplist(跳跃表):当上述条件不满足时,Redis 会采用 skiplist 作为内部编码。
注:上述中的默认值,也可以通过以下参数设置:zset-max-ziplist-entries 和 zset-max-ziplist-value。
BitMap(位图)
-
常用命令
SETBIT key offset value #设置或者修改key上的偏移量(offset)的位(value)的值,返回指定偏移量(offset)原来存储的值。如果offset过大,则会在中间填充0,offset最大到2^32-1,即可推出最大的字符串为512M(1Byte=8bits,1M=1024kb 1kb=1024bytes; 2^32-1=42949672965bits=536870912bytes=524288kb=512M) GETBIT key offset #查询key所存储的字符串值,获取偏移量上的位,返回指定key上的偏移量,若key不存在,那么返回0 BITCOUNT key [start end]#start end的单位是byte(1byte=8bit),此命令是获取[start end]区间内被设置为1的位bit的数量 BITOP AND destkey key1 key2#对一个或者对个key进行逻辑并操作,保存到destkey中 BITOP OR destkey key1 key2#对一个或者对个key进行逻辑或操作,保存到destkey中 BITOP XOR destkey key1 key2#对一个或者对个key进行逻辑异或操作,保存到destkey中 BITOP NOT destkey ket#对一个key进行逻辑非操作,保存到destkey中 #注:BITOP的时间复杂度是O(N),当处理大型矩阵或者大量数据统计时,最好将任务指派到附属节点(slave)进行,避免阻塞主节点。
-
使用场景
- 某一用户的纵向扩展,即每个key只记录当前业务属性的状态,每个uid当作bit位来记录信息(用户超过2^32-1内需要分片存储)
- 用户在线状态(key),offset(用户id),value(在线1,不在线0),大概42亿用户状态只需要512M
- 用户活跃,用户签到等等
-
为什么分片
- 在不密集分布中,长度过长,会有大量的0无用值占用内存资源
- bitmap有长度限制2^32-1
-
优势:
- 基于最小的单位bit进行存储,所以非常省空间。
- 设置时候时间复杂度O(1)、读取时候时间复杂度O(1),操作是非常快的
- 二进制数据的存储,进行相关计算的时候非常快。
- 方便扩容
-
bitmap和string的比较
数据类型 每个userid占用的空间 需要存储的用户量 全部内存量 string 32位 50,000,000 32位*5000w = 200M bitmap 1位 100,000,000 1位*1亿 = 12.5M
HyperLogLog
-
常用命令
PFADD key element1 element2 #添加指定元素到 HyperLogLog 中,影响基数估值则返回1否则返回0.若key不存在则创建,时间复杂度O(1) PFCOUNT key1 [key2] #返回key的基数个数;多个key时返回总个数,时间复杂度O(N) PFMERGE destkey key1 key2#合并多个key保存到destkey中,命令只会返回ok,时间复杂度O(N)
-
使用场景
每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数;基数不大,数据量不大就用不上,会有点大材小用浪费空间,有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么,和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmap 方便很多,一般可以bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃,hyperloglog计数
- 统计注册 IP 数
- 统计每日访问 IP 数
- 统计页面实时 UV 数
- 统计在线用户数
- 统计用户每天搜索不同词条的个数
GEO
-
常用命令
GEOADD key longitude latitude member [longitude latitude member ...] #用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。 GEOPOS key member1 member2 # 用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。 GEODIST key member1 member2 [m|km|ft|mi] #用于返回两个给定位置之间的距离 GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] #以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。 GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]#以给定的位置元素为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。 #m:米,默认 #km: 千米 #mi: 英里 #ft:英尺 #WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 #WITHCOORD: 将位置元素的经度和维度也一并返回。 #WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。 #COUNT 限定返回的记录数 #ASC: 查找结果根据距离从近到远排序。 #DESC: 查找结果根据从远到近排序。 GEOHASH key member1 member2 #使用 geohash 来保存地理位置的坐标,获取一个或多个位置元素的 geohash 值 注:GEO使用的是国际通用坐标系WGS-84。
-
使用场景
存储地理位置经纬度,查找距离范围的元素;如:每个商家门店有商家id(id)以及坐标位置(longitude,latitude),存储时可以将id作为位置名称,shop_positions作为key,查找附近商家列表(使用GEORADIUS命令)或者给定商家附近的商家列表(使用GEORADIUSBYMEMBER命令),得出所有的id,再使用id数组去数据库(或者redis中key为商家id的hash结构)查找对应的元素组合展示
Pub/Sub(发布订阅)
-
常用命令
SUBSCRIBE channel1 channel2 #订阅给定的一个或多个频道的信息 UNSUBSCRIBE channel1 channel2 #退订给定的频道 PUBLISH channel message #将信息发送到指定的频道 PUBSUB CHANNELS #返回由活跃频道组成的列表 PSUBSCRIBE pattern [pattern] #订阅一个或多个符合给定模式的频道 PUNSUBSCRIBE [pattern [pattern ...]] #退订所有给定模式的频道
-
使用场景
用作实时消息系统,比如普通的即时聊天,群聊等功能
Transactions(事务)
-
常用命令
MULTI #标记一个事务块的开始 EXEC #执行所有事务块内的命令