目录
Redis的单线程
Redis单线程快的原因
Redis 单线程处理高并发客户端连接
Redis数据结构
字符串(String)
常用方法
数据结构
哈希表(Hash)
常用方法
数据结构
列表(List)
常用方法
数据结构
集合(Set)
常用方法
数据结构
有序集合(Sorted Set)
常用方法
编辑
数据结构
总结
Redis的单线程
Redis的单线程主要是指 Redis的网络IO和键值对读写是由一个线程来完成的,这也是Redis 对外提供键值存储服务的主要流程。但Redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。
Redis单线程快的原因
所有的数据都在内存中,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能损耗问题。因为Redis是单线程,所以要小心使用Redis指令,对于那些耗时的指令(比如keys),一定要谨慎使用,一不小心就可能会导致Redis卡顿。
Redis 单线程处理高并发客户端连接
Redis的IO多路复用:redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。
Redis 将连接信息和事件封装成数据结构,并放入连接信息和事件队列中,也就是图中的I/O多路复用程序中,文件事件分派器负责从连接信息和事件队列中取出事件,然后将事件分发给相应的事件处理器。文件事件分派器可以通过轮询或其他方式从队列中获取待处理的事件。事件处理器执行与事件相关的操作。例如,对于一个读取事件,可能是从客户端读取数据;对于写入事件,可能是向客户端写入数据。事件处理器完成操作后,可能会产生新的事件,将这些事件放回队列,继续处理。
Redis数据结构
字符串(String)
常用方法
SET key value // 设置键的字符串值
GET key // 获取指定键的字符串值
INCR key // 将键的值递增1
DECR key // 将键的值递减1
APPEND key value // 在键的值后追加字符串
STRLEN key // 获取键的值的长度
GETRANGE key start end // 获取键的值的子字符串
SETRANGE key index value // 在指定索引开始处设置子字符串
MSET key1 value1 key2 value2 ... // 批量设置多个键的值
MGET key1 key2 ... // 批量获取多个键的值
DEL key // 删除指定的键
EXPIRE key seconds // 设置键的过期时间(秒)
SETNX key value // 键不存在时设置其值(分布式锁)
数据结构
简单动态字符串
1. int 表示方式
当字符串可以表示为整数时,Redis 将选择使用 int 表示。
SET mykey 42
2. embstr(嵌套字符串)表示方式
当字符串较短(小于44字节)时,Redis使用embstr表示。
SET shortstr "This is a short string"
3. raw 表示方式
当字符串较大时,Redis使用raw表示。
SET longstr "This is a longer string with spaces and special characters!"
哈希表(Hash)
常用方法
//设置哈希表字段的值,将哈希表key中的字段field的值设置为value。
HSET key field value
//获取哈希表字段的值,获取哈希表key中字段field的值。
HGET key field
//同时设置多个哈希表字段的值,一次性设置多个字段的值。
HMSET key field1 value1 field2 value2 ...
//同时获取多个哈希表字段的值,一次性获取多个字段的值。
HMGET key field1 field2 ...
//获取哈希表所有字段和值,返回哈希表 key 中所有字段和值。
HGETALL key
//删除哈希表字段,删除哈希表 key 中的一个或多个字段。
HDEL key field1 field2 ...
//判断哈希表字段是否存在,检查哈希表key中是否存在字段field。
HEXISTS key field
//获取哈希表所有字段,返回哈希表key中所有字段的列表。
HKEYS key
//获取哈希表所有值,返回哈希表key中所有值的列表。
HVALS key
//获取哈希表字段的数量,返回哈希表key中字段的数量。
HLEN key
数据结构
列表(List)
常用方法
// 在列表左侧插入元素,将一个或多个值插入到列表 key 的左侧。
LPUSH key value1 [value2 ...]
// 在列表右侧插入元素,将一个或多个值插入到列表 key 的右侧。
RPUSH key value1 [value2 ...]
// 从列表左侧弹出元素,移除并返回列表 key 的左侧第一个元素。
LPOP key
// 从列表右侧弹出元素,移除并返回列表 key 的右侧第一个元素。
RPOP key
// 获取列表范围内的元素,返回列表 key 中指定范围内的元素,范围由 start 和 stop 指定。
LRANGE key start stop
// 获取列表中指定索引的元素,返回列表 key 中指定索引 index 处的元素。
LINDEX key index
// 获取列表长度,返回列表 key 的长度。
LLEN key
// 在指定元素前或后插入新元素,在列表 key 中的元素 pivot 之前或之后插入新元素 value。
LINSERT key BEFORE|AFTER pivot value
// 移除列表中指定值的元素,从列表 key 中移除 count 个值为 value 的元素。
LREM key count value
// 修剪列表,修剪(裁剪)列表 key,保留指定范围内的元素。
LTRIM key start stop
数据结构
集合(Set)
常用方法
//向集合添加一个或多个元素,将一个或多个元素添加到集合 key 中。
SADD key member1 [member2 ...]
//获取集合的成员数,返回集合 key 中的元素个数。
SCARD key
//获取集合的所有成员,返回集合 key 中的所有成员。
SMEMBERS key
//判断元素是否是集合的成员,判断 member 是否是集合 key 的成员,返回 1 表示是成员,返回 0 表示不是成员。
SISMEMBER key member
//从集合中移除一个或多个元素
SREM key member1 [member2 ...]
//随机弹出集合中的一个元素
SPOP key
//随机获取集合中一个或多个元素
SRANDMEMBER key [count]
//计算多个集合的交集
SINTER key1 key2 [key3 ...]
//计算多个集合的并集
SUNION key1 key2 [key3 ...]
//计算多个集合的差集
SDIFF key1 key2 [key3 ...]
数据结构
Set集合是一个无序且不允许重复的集合
数据结构是哈希表。
有序集合(Sorted Set)
常用方法
//向有序集合添加一个或多个成员,或更新已存在成员的分数
//NX: 仅在成员不存在时添加。
//XX: 仅在成员已经存在时添加。
//CH: 修改对已经存在成员的分数。
//INCR: 对成员的分数进行自增操作。
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
//获取有序集合的成员数
ZCARD key
//获取成员在有序集合中的排名(从小到大)
ZRANK key member
//获取成员在有序集合中的排名(从大到小)
ZREVRANK key member
//按照排名范围获取有序集合的成员
ZRANGE key start stop [WITHSCORES]
//按照排名范围获取有序集合的成员(逆序)
ZREVRANGE key start stop [WITHSCORES]
//从有序集合中移除一个或多个成员
ZREM key member [member ...]
//对有序集合中的成员的分数进行增加操作
ZINCRBY key increment member
//获取有序集合中成员的分数
ZSCORE key member
//计算多个有序集合的交集,并将结果存储在新的有序集合中
//计算给定的 numkeys 个有序集合的交集,并将结果存储在新的有序集合 destination 中。可选参数 WEIGHTS 可以为每个集合指定权重,AGGREGATE 参数指定聚合方式。
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
//计算多个有序集合的并集,并将结果存储在新的有序集合中
//计算给定的 numkeys 个有序集合的并集,并将结果存储在新的有序集合 destination 中。可选参数 WEIGHTS 可以为每个集合指定权重,AGGREGATE 参数指定聚合方式。
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
数据结构
数据可以使用压缩列表或者跳表来存储,一般用跳表比较多,如下图:
跳表:(根据分数排好序的有序链表)
原始的跳表就是一个链表,链表查找元素慢,插入元素快。在链表上做了优化改进。将有序链表改造为支持折半查找的算法结构。改造后支持查找、插入、删除操作。(空间换时间,使用较多)
压缩列表:
压缩列表最原始的底层就是链表,只不过这个链表去掉了指针,像是数组一样。根据偏移量可以快速定位元素。(使用不是很多)
总结
redis的压缩列表跟跳表那个快用那个,默认zset中有128个元素就切换成跳表插入。(什么时候用跳表跟压缩列表也可以自行设置)