Redis
简介
Redis是一个开源的key-value存储系统。存储在内存中。
相比于Memcached,value类型相对更多,string、list、set、zset、hash。
Redis操作都是原子性的,单线程多路IO复用
Redis支持各种不同方式的排序。
keys * 查看当前库所有key
exists key 判断某个key是否存在
type key 查看你的key是什么类型
del key 删除指定的key
unlink key 根据value选择非阻塞删除
expire key 10 为key设定过期时间
ttl key 查看还有多少秒过期 -1永不过期、-2已过期
string
String 类型是二进制安全的。意味着 Redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。
操作
set <key><value>添加键值对
*NX:当数据库中 key 不存在时,可以将 key-value 添加数据库
*XX:当数据库中 key 存在时,可以将 key-value 添加数据库,与 NX 参数互斥
*EX:key 的超时秒数
*PX:key 的超时毫秒数,与 EX 互斥
get <key>查询对应键值
append <key><value>将给定的<value> 追加到原值的末尾
strlen <key>获得值的长度
setnx <key><value>只有在 key 不存在时 设置 key 的值
incr <key>
将 key 中储存的数字值增 1
只能对数字值操作,如果为空,新增值为 1
decr <key>
将 key 中储存的数字值减 1
只能对数字值操作,如果为空,新增值为-1
incrby / decrby <key><步长>将 key 中储存的数字值增减。自定义步长。
mset <key1><value1><key2><value2> .....
同时设置一个或多个 key-value 对
mget <key1><key2><key3> .....
同时获取一个或多个 value
msetnx <key1><value1><key2><value2> .....
同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
getrange <key><起始位置><结束位置>
获得值的范围,类似 java 中的 substring,前包,后包
setrange <key><起始位置><value>
用 <value> 覆写<key>所储存的字符串值,从<起始位置>开始(索引从 0 开始)。
setex <key><过期时间><value>
设置键值的同时,设置过期时间,单位秒。
getset <key><value>
以新换旧,设置了新值同时获得旧值。
数据结构
String 的数据结构为简单动态字符串(Simple Dynamic String,缩写 SDS)。是可以修改的字符串,内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配.
List
单键多值
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
操作
lpush/rpush <key><value1><value2><value3> .... 从左边/右边插入一个或多个值。
lpop/rpop <key>从左边/右边吐出一个值。值在键在,值光键亡。
rpoplpush <key1><key2>从<key1>列表右边吐出一个值,插到<key2>列表左边。
lrange <key><start><stop> 按照索引下标获得元素(从左到右)
lrange mylist 0 -1 0 左边第一个,-1 右边第一个,(0-1 表示获取所有)
lindex <key><index>按照索引下标获得元素(从左到右)
llen <key>获得列表长度
linsert <key> before <value><newvalue>在<value>的后面插入<newvalue>插入值
lrem <key><n><value>从左边删除 n 个 value(从左到右)
lset<key><index><value>将列表 key 下标为 index 的值替换成 value
数据结构
List 的数据结构为快速链表 quickList。
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是 ziplist,也即是压缩列表。
它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成 quicklist。
因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是 int 类型的数据,结构上还需要两个额外的指针 prev 和 next。
Redis 将链表和 ziplist 结合起来组成了 quicklist。也就是将多个 ziplist 使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
Set
Redis set 对外提供的功能与 list 类似是一个列表的功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,并且 set 提供了判断某个成员是否在一个 set 集合内的重要接口,
这个也是 list 所不能提供的。Redis 的 Set 是 string 类型的无序集合。它底层其实是一个 value 为 null 的 hash 表,所以添加,删除,查找的复杂度都是 O(1)。
一个算法,随着数据的增加,执行时间的长短,如果是 O(1),数据增加,查找数据的时间不变
操作
sadd <key><value1><value2> .....
将一个或多个 member 元素加入到集合 key 中,已经存在的 member 元素将被忽略
smembers <key>取出该集合的所有值。
sismember <key><value>判断集合<key>是否为含有该<value>值,有 1,没有 0
scard<key>返回该集合的元素个数。
srem <key><value1><value2> .... 删除集合中的某个元素。
spop <key>随机从该集合中吐出一个值。
srandmember <key><n>随机从该集合中取出 n 个值。不会从集合中删除 。
smove <source><destination>value 把集合中一个值从一个集合移动到另一个集合
sinter <key1><key2>返回两个集合的交集元素。
sunion <key1><key2>返回两个集合的并集元素。
sdiff <key1><key2>返回两个集合的差集元素(key1 中的,不包含 key2 中的)
数据结构
Set 数据结构是 dict 字典,字典是用哈希表实现的。Java 中 HashSet 的内部实现使用的是 HashMap,只不过所有的 value 都指向同一个对象。Redis 的 set 结构也是一样,它的内部也使用 hash 结构,所有的 value 都指向同一个内部值。
Hash
Redis hash 是一个键值对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
类似 Java 里面的 Map<String,Object>
用户 ID 为查找的 key,存储的 value 用户对象包含姓名,年龄,生日等信息,如果用普通的 key/value 结构来存储
操作
hset <key><field><value>给<key>集合中的 <field>键赋值<value>
hget <key1><field>从<key1>集合<field>取出 value
hmset <key1><field1><value1><field2><value2>... 批量设置 hash 的值
hexists<key1><field>查看哈希表 key 中,给定域 field 是否存在。
hkeys <key>列出该 hash 集合的所有 field
hvals <key>列出该 hash 集合的所有 value
hincrby <key><field><increment>为哈希表 key 中的域 field 的值加上增量 1 -1
hsetnx <key><field><value>将哈希表 key 中的域 field 的值设置为 value ,当且仅当域field 不存在 .
数据结构
Hash 类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value 长度较短且个数较少时,使用ziplist,否则使用hashtable。
Zset
Redis 有序集合 zset 与普通集合 set 非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了 。
因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。
访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。
操作
zadd <key><score1><value1><score2><value2>… 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
zrange <key><start><stop> [WITHSCORES] 返回有序集 key 中,下标在<start><stop>之间的元素
带 WITHSCORES,可以让分数一起和值返回到结果集。 zrangebyscore key minmax [withscores] [limit offset count]
返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。
zrevrangebyscore key maxmin [withscores] [limit offset count] 同上,改为从大到小排列。
zincrby <key><increment><value> 为元素的 score 加上增量
zrem <key><value>删除该集合下,指定值的元素
zcount <key><min><max>统计该集合,分数区间内的元素个数
zrank <key><value>返回该值在集合中的排名,从 0 开始。
数据结构
SortedSet(zset)是 Redis 提供的一个非常特别的数据结构,一方面它等价于 Java的数据结构 Map<String, Double>,可以给每一个元素 value 赋予一个权重 score,另一方面它又类似于 TreeSet,内部的元素会按照权重 score 进行排序,可以得到每个元素的名次,还可以通过 score 的范围来获取元素的列表。
zset 底层使用了两个数据结构
(1)hash,hash 的作用就是关联元素 value 和权重 score,保障元素 value 的唯一性,可以通过元素 value 找到相应的 score 值。
(2)跳跃表,跳跃表的目的在于给元素 value 排序,根据 score 的范围获取元素列表。
Bitmaps
(1) Bitmaps 本身不是一种数据类型, 实际上它就是字符串(key-value) ,但是它可以对字符串的位进行操作。
(2) Bitmaps 单独提供了一套命令, 所以在 Redis 中使用 Bitmaps 和使用字符串的方法不太相同。 可以把 Bitmaps 想象成一个以位为单位的数组,数组的每个单元只能存储 0 和 1, 数组的下标在 Bitmaps 中叫做偏移量。
操作
setbit<key><offset><value>设置 Bitmaps 中某个偏移量的值(0 或 1) 偏移从0开始
getbit<key><offset>获取 Bitmaps 中某个偏移量的值 offset 位的值,从 0 开始算
bitcount
统计字符串被设置为 1 的 bit 数。一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。start 和 end 参数的设置,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,start、end 是指 bit 组的字节的下标数,二者皆包含。
举例: K1 【01000001 01000000 00000000 00100001】,对应【0,1,2,3】
bitcount<key>[start end] 统计字符串从 start 字节到 end 字节比特值为 1 的数量
bitop
bitop and(or/not/xor) <destkey> [key…]
bitop 是一个复合操作, 它可以做多个 Bitmaps 的 and(交集) 、 or(并集) 、 not(非) 、 xor(异或) 操作并将结果保存在 destkey 中。
Redis 的发布和订阅
1、 打开一个客户端订阅 channel1
SUBSCRIBE channel1
2、打开另一个客户端,给 channel1 发布消息 hello
publish channel1 hello
3、打开第一个客户端可以看到发送的消息
注:发布的消息没有持久化,如果在订阅的客户端收不到 hello,只能收到订阅后发布的消息
Redis 的事务
Redis 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事
务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
Redis 事务的主要作用就是串联多个命令防止别的命令插队
Multi Exec discard
从输入 Multi 命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入
Exec 后,Redis 会将之前的命令队列中的命令依次执行。
组队的过程中可以通过 discard 来放弃组队。
组队中某个命令出现了报告错误,执行时整个的所有队列都会被取消。 如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。
WATCH key [key ...]
在执行 multi 之前,先执行 watch key1 [key2],可以监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
unwatch
取消 WATCH 命令对所有 key 的监视。
如果在执行 WATCH 命令之后,EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行 UNWATCH 了。
Redis 事务三特性
单独的隔离操作
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
没有隔离级别的概念
队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行
不保证原子性
事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚
Redis持久化
Redis 提供两种持久化机制 RDB 和 AOF 机制:
1、 RDB(Redis DataBase)持久化方式:是指用数据集快照的方式半持久化模式 )记录 redis数据库的所有键值对 ,在某个时 间点将数据写入一 个临时文件,持久化结束 后,用这个临时文件替换上次持久化的文件,达到数据恢复 。
优点:
1、只 有一 个文 件 dump.rdb,方 便持 久化 。
2、容 灾性 好,一个文件 可以 保存 到安 全的 磁盘 。
3、性能最大化 ,fork 子进程来完成写操作, 让主进程继续 处理 命令 ,所 以是 IO最大化。使用 单独子进 程来进行持久化 ,主进程不会进 行任 何 IO 操作 。保证了 redis的高 性能 ) 4.相对于数据集大时 ,比 AOF的启动效 率更高。
缺点:
数据 安全 性低 。RDB 是间 隔一 段时 间进 行持 久化 ,如果 持久 化之 间 redis 发生故障 ,会 发生 数据 丢失 。所以这种方式更适合数据要求不严谨的时候 )
2、 AOFAppend-only file)持久化方式:是指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储)保存为 aof 文件 。
优点:
1、数 据安 全, aof 持久 化可 以配 置 appendfsync 属性 ,有 always,每 进行 一次命令 操作 就记 录到 aof 文件 中一 次。
2、通 过 append 模式 写文 件, 即使 中途 服务 器宕 机, 可以 通过 redis-check-aof工具 解决 数据 一致 性问 题。
3、AOF 机制 的 rewrite 模式 。AOF文件没被 rewrite 之前( 文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如 误操作的 flushall))
缺点:
1、 AOF文件比RDB文件大,且恢复速度慢 。
2、数据集大的时候 ,比rdb启动效率低。
标签:元素,Redis,value,命令,key,集合,随笔 From: https://www.cnblogs.com/tyt0o0/p/17301364.html