[关闭]
@mritd 2016-01-14T13:42:43.000000Z 字数 8825 阅读 1722

Redis学习笔记

Redis


hexo_redis_logo

一、简介

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(有序集合)和hashs(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。

redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。

二、Redis功能

  1. Redis 的Sharding

    Redis 支持客户端的Sharding 功能,通过一致性hash 算法实现,当前Redis 不支持故障冗余,在集群中不能在线增加或删除Redis。

  2. Redis 的master/slave 复制

    一个master 支持多个slave;Slave 可以接受其他slave 的连接来替代他连接master;复制在master 是非阻塞的,而在slave 是阻塞的;复制被利用来提供可扩展性,在slave 端只提供查询功能及数据的冗余。

  3. Redis 的Virtual Memory 功能(VM)

    vm 是Redis2.0 新增的一个非常稳定和可靠的功能,vm 的引入是为了提高Redis 的性能,也就是把很少使用的value 保存到disk,而key 保存在内存中。实际上就是如果你有10w 的keys 在内存中,而只有仅仅10%左右的key 经常使用,那么Redis 可以通过开启VM 尝试将不经常使用的Value 转换到disk 上保存。

  4. Redis 的附加档案(AOF)功能

    Redis 通过配置的策略将数据集保存到aof 中,当Redis 挂掉后能够通过aof 恢复到挂掉前的状态

三、Redis 数据类型

Hashes 相关方法如下

  1. hset(key, field, value) 向名称为keyhash中添加元素field<—>value
  2. hget(key, field) 返回名称为keyhashfield对应的value
  3. hmget(key, field1,...,field N) 返回名称为keyhashfield i对应的value
  4. hmset(key, field1, value1,...,field N, value N) 向名称为keyhash中添加元素field i<—>value i
  5. hincrby(key, field, integer) 将名称为keyhashfieldvalue增加integer
  6. hexists(key, field) 名称为keyhash中是否存在键为field的域
  7. hdel(key, field) 删除名称为keyhash中键为field的域
  8. hlen(key) 返回名称为keyhash中元素个数
  9. hkeys(key) 返回名称为keyhash中所有键
  10. hvals(key) 返回名称为keyhash中所有键对应的value
  11. hgetall(key) 返回名称为keyhash中所有的键(field)及其对应的value

示例操作如下

  1. redis> HMSET user:1000 username antirez password P1pp0 age 34
  2. OK
  3. redis> HGETALL user:1000
  4. 1) "username"
  5. 2) "antirez"
  6. 3) "password"
  7. 4) "P1pp0"
  8. 5) "age"
  9. 6) "34"
  10. redis> HSET user:1000 password 12345
  11. (integer) 0
  12. redis> HGETALL user:1000
  13. 1) "username"
  14. 2) "antirez"
  15. 3) "password"
  16. 4) "12345"
  17. 5) "age"
  18. 6) "34"
  19. redis>

四、Redis 数据类型的常用操作

由于命令太多,所以不一一列举,具体参考 Redis命令参考,文档已进行离线缓存 Redis命令手册下载

字符串

SET

将字符串值 value 关联到 key (设置值)。
如果 key 已经持有其他值,SET 就覆写旧值,无视类型。
对于某个原本带有生存时间(TTL)的键来说,当 SET 命令成功在这个键上执行时,这个键原有的 TTL 将被清除。

可选参数

可接受的语法

  1. SET KEY VALUE [OPTION] [OPTION_VALUE]

代码示例

  1. SET a 10 # 设置 key a value 10
  2. SET a 10 EX 10 # 同上,但有效期为10秒,过期后再 get key 则返回nil
  3. SET a 10 PX 10000 # 同上,有效期为10000毫秒
  4. SET a 10 NX # 仅当 a 不存在时才进行设置,否则返回错误
  5. SET a 10 XX # 仅当 a 存在时进行设置

GET

返回 key 所关联的字符串值。(获取值)
如果 key 不存在那么返回特殊值 nil
假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。

可接受的语法

  1. GET KEY

代码示例

  1. SET a 10 # 先设置一个值
  2. GET a # 获取 a 的值,此时 a 必须为String,否则返回错误
  3. GET b # 尝试获取一个不存在的值时 返回nil

同时设置一个或多个 key-value 对。
如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。
MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。

可接受的语法

  1. MSET KEY1 VALUE1 KEY2 VALUE2 ...

代码示例

  1. MSET a 10 b 11 c 12 # 同时设置 a、b、c的值,要么全部成功要么全部失败

MGET

返回所有(一个或多个)给定 key 的值。
如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil。因此,该命令永不失败。

可接受的语法

  1. MGET KEY1 KEY2 KEY3 ...

代码示例

  1. localhost:6379> MSET a 10 b 11 c 12
  2. OK
  3. localhost:6379> MGET a b c d # d 不存在 则返回 nil
  4. 1) "10"
  5. 2) "11"
  6. 3) "12"
  7. 4) (nil)
  8. localhost:6379>

SETRANGE

value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始。不存在的 key 当作空白字符串处理。可以理解为对指定位置字符串覆盖
SETRANGE 命令会确保字符串足够长以便将 value 设置在指定的偏移量上,如果给定 key 原来储存的字符串长度比偏移量小(比如字符串只有5个字符长,但你设置的 offset 是10),那么原字符和偏移量之间的空白将用零字节(zerobytes,"\x00")来填充。
注意你能使用的最大偏移量是 2^29-1(536870911) ,因为 Redis 字符串的大小被限制在 512 兆(megabytes)以内。如果你需要使用比这更大的空间,你可以使用多个 key 。

当生成一个很长的字符串时,Redis 需要分配内存空间,该操作有时候可能会造成服务器阻塞(block)。在2010年的Macbook Pro上,设置偏移量为 536870911(512MB 内存分配),耗费约 300 毫秒,设置偏移量为 134217728(128MB 内存分配),耗费约 80 毫秒,设置偏移量 33554432(32MB 内存分配),耗费约 30 毫秒,设置偏移量为 8388608(8MB 内存分配),耗费约 8 毫秒。注意若首次内存分配成功之后,再对同一个 key 调用 SETRANGE 操作,无须再重新内存。

可接受的语法

  1. SETRANGE KEY STR_VALUE

代码示例

  1. localhost:6379> SET a "123456789"
  2. OK
  3. localhost:6379> SETRANGE a 5 "XX"
  4. (integer) 9
  5. localhost:6379> GET a
  6. "12345XX89"
  7. localhost:6379> SETRANGE a 5 "XXXXXXXXXXXXXX" # 超过原有长度自动拼接
  8. (integer) 19
  9. localhost:6379> GET a
  10. "12345XXXXXXXXXXXXXX"
  11. localhost:6379> SETRANGE a 7 "XXXX" # 不够的话自动用 \x00 占位
  12. (integer) 11
  13. localhost:6379> GET a
  14. "123\x00\x00\x00\x00XXXX"

GETRANGE

返回 key 中字符串值的子字符串,字符串的截取范围由 startend 两个偏移量决定(包括 start 和 end 在内)。负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推。GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。

在 <= 2.0 的版本里,GETRANGE 被叫作 SUBSTR。

可接受的语法

  1. GETRANGE KEY START_INDEX END_INDEX

代码示例

  1. localhost:6379> SET a "test GETRANGE"
  2. OK
  3. localhost:6379> GETRANGE a 0 3 # 获取0~3位置字符
  4. "test"
  5. localhost:6379> GETRANGE a 0 100 # 超过长度则表示获取全部
  6. "test GETRANGE"
  7. localhost:6379> GETRANGE a -3 -1 # 获取只能从左到右获取
  8. "NGE"
  9. localhost:6379> GETRANGE a -1 -3 # 回绕操作将返回空串
  10. ""
  11. localhost:6379> GETRANGE a 0 -1 # 正确的获取全部字符串
  12. "test GETRANGE"
  13. localhost:6379>

APPEND

如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。如果 key 不存在,APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。

可接受的语法

  1. APPEND KEY STRING_VALUE

代码示例

  1. localhost:6379> EXISTS b # b 不存在
  2. (integer) 0
  3. localhost:6379> APPEND b "test not exists" # 此时进行 APPEND 操作等同于 SET
  4. (integer) 15
  5. localhost:6379> GET b
  6. "test not exists"
  7. localhost:6379> APPEND b "XXXXXXX" # 拼接字符串
  8. (integer) 22
  9. localhost:6379> GET b
  10. "test not existsXXXXXXX"
  11. localhost:6379>

List类型

List类型是按照插入顺序排序的字符串链表。和普通链表一样,可以在其头部和尾部添加新的元素。插入时,如果该键不存在,将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295

从元素插入和删除的效率来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。如果元素插入或删除操作是作用于链表中间,那将会是非常低效的

RPUSH/LPUSH

将一个或多个值放入 List中,RPUSH 新加入的元素将放在 List 链表尾部(右),LPUSH 同理放在左边,如果对应的 Listkey 不存在,将自动创建一个 List,并将值放入 Listkey 存在,且不是 List 类型时,将返回错误

可接受的语法

  1. RPUSH/LPUSH KEY VALUE1 VALUE2 VALUE3 # 同时放入多个值
  2. RPUSH/LPUSH KEY VALUE # 每次只放入一个值

代码示例

  1. localhost:6379> RPUSH list1 1 2 3 4
  2. (integer) 4
  3. localhost:6379> LRANGE list1 0 -1 # 获取List所有值
  4. 1) "1"
  5. 2) "2"
  6. 3) "3"
  7. 4) "4"
  8. localhost:6379>

LLEN

返回指定 List 的长度,如果给定的 KEY 不存在则返回0,如果给定的 KEY 不是 List 类型将返回错误

可接受的语法

  1. LLEN KEY

代码示例

  1. localhost:6379> LLEN list1
  2. (integer) 4
  3. localhost:6379> LLEN L
  4. (integer) 0
  5. localhost:6379>

LRANGE

返回指定返回的 List 的值,如果开始值大于 List 的长度,那么将返回空列表,如果结束值大于 List 长度,那么将示结束值为 List 最大长度

可接受的语法

  1. LRANGE KEY START END

代码示例

  1. localhost:6379> LRANGE list1 0 3
  2. 1) "1"
  3. 2) "2"
  4. 3) "3"
  5. 4) "4"
  6. localhost:6379> LRANGE list1 10 11
  7. (empty list or set)
  8. localhost:6379> LRANGE list1 0 1000
  9. 1) "1"
  10. 2) "2"
  11. 3) "3"
  12. 4) "4"

LTRIM

截取列表指定位置的元素,当Start值大于 List 长度时,将返回空列表;当End值大于 List 长度时,示End值为 List 长度

可接受的语法

  1. LTRIM KEY START END

代码示例

  1. localhost:6379> RPUSH list 1 2 3 4 5 6 7 8 9 10
  2. (integer) 10
  3. localhost:6379> LTRIM list 1 9
  4. OK
  5. localhost:6379> LRANGE list 0 -1
  6. 1) "2"
  7. 2) "3"
  8. 3) "4"
  9. 4) "5"
  10. 5) "6"
  11. 6) "7"
  12. 7) "8"
  13. 8) "9"
  14. 9) "10"
  15. localhost:6379> LTRIM list 5 100
  16. OK
  17. localhost:6379> LRANGE list 0 -1
  18. 1) "7"
  19. 2) "8"
  20. 3) "9"
  21. 4) "10"
  22. localhost:6379> LTRIM list 50 100
  23. OK
  24. localhost:6379> LRANGE list 0 -1
  25. (empty list or set)
  26. localhost:6379>

LINDEX

获取指定位置的值,超出位置(不在 List 范围内)返回nil

可接受的语法

  1. LINDEX KEY INDEX

代码示例

  1. localhost:6379> RPUSH list 1 2 3 4 5 6 7 8 9
  2. (integer) 9
  3. localhost:6379> LINDEX list 3
  4. "4"
  5. localhost:6379> LINDEX list 100
  6. (nil)
  7. localhost:6379>

LREM

移除列表中与指定值相等的元素,

在最新版本 3.0.6测试,无论下面的 count等于多少,都会移除所有目标值,只是搜索方向问题,尚不清楚原因

可接受的语法

  1. LREM KEY COUNT VALUE

代码示例

  1. localhost:6379> RPUSH list 0 0 xxx 0 xxx xxx 0 0 0 xxx 0
  2. (integer) 11
  3. localhost:6379> LRANGE list 0 -1
  4. 1) "0"
  5. 2) "0"
  6. 3) "xxx"
  7. 4) "0"
  8. 5) "xxx"
  9. 6) "xxx"
  10. 7) "0"
  11. 8) "0"
  12. 9) "0"
  13. 10) "xxx"
  14. 11) "0"
  15. localhost:6379> LREM list 5 xxx
  16. (integer) 4
  17. localhost:6379> LRANGE list 0 -1
  18. 1) "0"
  19. 2) "0"
  20. 3) "0"
  21. 4) "0"
  22. 5) "0"
  23. 6) "0"
  24. 7) "0"
  25. localhost:6379> del list
  26. (integer) 1
  27. localhost:6379> RPUSH list 0 0 xxx 0 xxx xxx 0 0 0 xxx 0
  28. (integer) 11
  29. localhost:6379> LRANGE list 0 -1
  30. 1) "0"
  31. 2) "0"
  32. 3) "xxx"
  33. 4) "0"
  34. 5) "xxx"
  35. 6) "xxx"
  36. 7) "0"
  37. 8) "0"
  38. 9) "0"
  39. 10) "xxx"
  40. 11) "0"
  41. localhost:6379> LREM list 6 "xxx"
  42. (integer) 4
  43. localhost:6379> LRANGE list 0 -1
  44. 1) "0"
  45. 2) "0"
  46. 3) "0"
  47. 4) "0"
  48. 5) "0"
  49. 6) "0"
  50. 7) "0"
  51. localhost:6379> del list
  52. (integer) 1
  53. localhost:6379> RPUSH list 0 0 xxx 0 xxx xxx 0 0 0 xxx 0
  54. (integer) 11
  55. localhost:6379> LREM list -6 "xxx"
  56. (integer) 4
  57. localhost:6379> LRANGE list 0 -1
  58. 1) "0"
  59. 2) "0"
  60. 3) "0"
  61. 4) "0"
  62. 5) "0"
  63. 6) "0"
  64. 7) "0"
  65. localhost:6379> del list
  66. (integer) 1
  67. localhost:6379> RPUSH list 0 0 xxx 0 xxx xxx 0 0 0 xxx 0
  68. (integer) 11
  69. localhost:6379> LREM list 0 "xxx"
  70. (integer) 4
  71. localhost:6379> del list
  72. (integer) 1
  73. localhost:6379> RPUSH list 0 0 xxx 0 xxx xxx 0 0 0 xxx 0
  74. (integer) 11
  75. localhost:6379>

LSET

向指定位置设置值,列表 KEY 不存在将返回错误,坐标不对返回对应错误信息

可接受的语法

  1. LSET KEY INDEX VALUE

代码示例

  1. localhost:6379> RPUSH list 1 1 1 1 1
  2. (integer) 5
  3. localhost:6379> LSET list 2 xxxx
  4. OK
  5. localhost:6379> LRANGE list 0 -1
  6. 1) "1"
  7. 2) "1"
  8. 3) "xxxx"
  9. 4) "1"
  10. 5) "1"
  11. localhost:6379>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注