Redis (必看)

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介: Redis 学习点滴 知识分享

redis



字符串
SET Key Value  会覆盖原有的value
SET Key Value EX 10
SETNX  成功1 失败0
EXISTS 存在1 不存在0
原子操作atomic
SETEX    秒  
PSETEX 毫秒
GET
GETSET   获取key原有的值并SET对应的value
STRLEN  获取key对应value的长度
SETRANGE  key  offset value 从偏移量开始进行覆盖 如果偏移量之前为空 则用零字节 \x00代替
GETRANGE key start end  截取-1代表末尾
INCR key 自增
如果键 key 不存在, 那么它的值会先被初始化为 0 , 然后再执行 INCR 命令
如果键 key 储存的值不能被解释为数字, 那么 INCR 命令将返回一个错误。
INCR key
在key基础上进行运算操作,若不存在key,则从0开始进行运算。
INCRBY key  increment  
INCRBYFLOAT key  floatIncrement 浮点操作
DECR  key  自减
DECRBY key  decrement
原子性操作atomic
MSET 同时为多个键设置值
MSET name zhangsan sex man age 18 address china
MGET name sex age address

MSETNX  当且仅当所有给定键都不存在时, 为所有给定键设置值。
即使只有一个给定键已经存在, MSETNX 命令也会拒绝执行对所有键的设置操作

哈希表
HSET  表名 key value
HSETNX  
HGET
HEXISTS 表名 key
HDEL
HLEN
HSTRLEN
HINCRBY 表名 key  increment
HINCRBYFLOAT
HMSET
HMGET
HKEYS key
HGETALL
列表
LPUSH key  elments...  返回key的长度
LPUSHX key elemnts...    当key不存在的时候 LPUSHX 什么也不做
RPUSH key elments... 返回key长度
RPUSHX key elements
LPOP key  移除列表的头元素
RPOP key 移除列表的尾元素
RPOPLPUSH 在一个原子时间内,执行以下两个动作
将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。
将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。
安全的队列
使用 RPOPLPUSH 命令(或者它的阻塞版本 BRPOPLPUSH source destination timeout )可以解决这个问题:因为它不仅返回一个消息,同时还将这个消息添加到另一个备份列表当中,如果一切正常的话,当一个客户端完成某个消息的处理之后,可以用 LREM key count value 命令将这个消息从备份表删除。还可以添加一个客户端专门用于监视备份表,它自动地将超过一定处理时限的消息重新放入队列中去(负责处理该消息的客户端可能已经崩溃),这样就不会丢失任何消息了。
循环列表
通过使用相同的 key 作为 RPOPLPUSH 命令的两个参数,客户端可以用一个接一个地获取列表元素的方式,取得列表的所有元素,而不必像 LRANGE key start stop 命令那样一下子将所有列表元素都从服务器传送到客户端中(两种方式的总复杂度都是 O(N))。
以上的模式甚至在以下的两个情况下也能正常工作:
有多个客户端同时对同一个列表进行旋转(rotating),它们获取不同的元素,直到所有元素都被读取完,之后又从头开始。
有客户端在向列表尾部(右边)添加新元素。
这个模式使得我们可以很容易实现这样一类系统:有 N 个客户端,需要连续不断地对一些元素进行处理,而且处理的过程必须尽可能地快。一个典型的例子就是服务器的监控程序:它们需要在尽可能短的时间内,并行地检查一组网站,确保它们的可访问性。
注意,使用这个模式的客户端是易于扩展(scala)且安全(reliable)的,因为就算接收到元素的客户端失败,元素还是保存在列表里面,不会丢失,等到下个迭代来临的时候,别的客户端又可以继续处理这些元素了。
LREM  key count  value
count 的值可以是以下几种:
count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
count = 0 : 移除表中所有与 value 相等的值。
LLEN  key  
LINDEX key index  返回对应下标的value
LINSERT key  BEFORE|AFTER  piovt element  
LSET key index value
将列表 key 下标为 index 的元素的值设置为 value 。
LTRIM key start end
BRPOPLPUSH
集合
SADD key  value...
SISMEMBER key value 判断元素是否在集合
SPOP key 随机移除一个元素
SRANDMEMBER key count  返回key集合中count个不相同的元素
如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。
SMOVE  soure target value  把value从原集合移动到目标集合
SCARD key  返回集合元素的数量
SMEMBERS key  返回集合所有的元素
SINTER key key 返回两个集合的交集
SINTERSTORE  target key key 把两个集合的交集给target
SUNION  key key 返回所有集合的并集
SUNIONSTORE  target key key 把两个集合的并集给target
SDIFF key key1 key2....   返回key与其他key之间的差集
SDIFFSTORE target key1 key2...  把集合的差集给target
有序集合    


ZADD  key score vlaue
ZSCORE key  value 返回key 中 value对应的score
ZINCRBY  key  increment  value    key中的value 增加increment
ZCARD key  返回key中有多少个value                              
ZCOUNT key min max  返回key中符合min max之间的数量 闭区间
ZRANGE key start stop WITHSCORES
ZREVRANGE key start stop WITHSCORES
ZRANGERBYSCORE  
ZRANGEBYSCORE rank -inf +inf [withscores]
ZREVRANGEBYSCORE  与 ZRANGERBYSCORE
ZREVRANGEBYSCORE rank  +inf -infZRANK key  value  显示对应value在key中的排名 从小到大
返回值为value的下标
ZRANK rank player3
ZREVRANK rank player3
ZREM key value
ZREM rank player
ZREMRANGEBYRANK key start stop  按照排名移除元素  
ZREMRANGEBYRANK rank  0 1
ZREMRANGEBYRANK key start stop  按照分数(闭区间)移除元素  
ZREMRANGEBYSCORE rank 1200  1249
ZRANGEBYLEX rank  - (playerXX   按照字节范围进行排序返回元素
ZLEXCOUNT   [a [f  返回开闭区间范围内的元素数量
ZLEXCOUNT myset - +
ZREMRANGEBYLEX  移除开闭区间 a->d内元素
ZREMRANGEBYLEX myset (a (d
ZUNIONSTORE   求并集
#给alibaba的所有元素乘1.5倍 把programmer和alibaba乘后的结果赋值给zijiedance
ZUNIONSTORE  zijiedance 2  programmer alibaba WEIGHTS 1 1.5  
ZINTERSTORE    交集
HYPERLOGLOG(基数统计)
PFADD
PFADD database redis mongodb mysql
PFCOUNT
PFCOUNT dababase
PFMERGE
PFMERGE phone iphone huawei
地理位置
GEOADD
GEOADD shanxi  123.333 23.333 "xi'an" 120.222 12.222 "weinan"
GEOPOS
GEOPOS shanxi  "xi'an" "weinan"
GEODIST
GEODIST road1 beijing shanghai kmGEORADIUS    给定经纬度 返回key中符合范围区间的 元素
GEORADIUS mycity 1.25 1.25 50 km withdist  withcoord
GEORADIUSBYMEMBER 不在传入经纬度而是取元素的经纬度
GEORADIUSBYMEMBER mycity cityMid 20 km withcoord withdist
GEOHASH

位图
SETBIT key value   1/0
setbit wenwen 0 0
GETBIT key offset
GETBIT wenwen 3
BITCOUNT key start end     统计wenwen用户一共从0-111天上线了多少次
bitcount wenwen 0 111
使用 bitmap 实现用户上线次数统计
Bitmap 对于一些特定类型的计算非常有效。
假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户 A 上线了多少天,用户 B 上线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加 beta 测试等活动 —— 这个模式可以使用 SETBIT key offset valueBITCOUNT key [start] [end] 来实现。
比如说,每当用户在某一天上线的时候,我们就使用 SETBIT key offset value ,以用户名作为 key ,将那天所代表的网站的上线日作为 offset 参数,并将这个 offset 上的为设置为 1 。
举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。
当要计算 peter 总共以来的上线次数时,就使用 BITCOUNT key [start] [end] 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。
性能
前面的上线次数统计例子,即使运行 10 年,占用的空间也只是每个用户 10*365 比特位(bit),也即是每个用户 456 字节。对于这种大小的数据来说, BITCOUNT key [start] [end] 的处理速度就像 GET keyINCR key 这种 O(1) 复杂度的操作一样快。
如果你的 bitmap 数据非常大,那么可以考虑使用以下两种方法:
1将一个大的 bitmap 分散到不同的 key 中,作为小的 bitmap 来处理。使用 Lua 脚本可以很方便地完成这一工作。
2使用 BITCOUNT key [start] [end] 的 start 和 end 参数,每次只对所需的部分位进行计算,将位的累积工作(accumulating)放到客户端进行,并且对结果进行缓存 (caching)。
BITPOS
SETBIT bits 3 1  #1000
BITPOS bits 0 0  BITPOS bits 1 3
数据库
1检查key是否存在
set db redis
EXISTS db
del db
2判断类型
set week "week1"
TYPE week
3RENAME  重命名key 覆盖内容
rename android hongmeng
4MOVE 移动源数据库中的key到目标数据库
move jame 1
5DEL 删除key
del james
6FLUSHDB   清空数据库中的全部key
7RANDOMKEY 从数据库中随机获取一个key
8DBSIZE 当前数据库中key的数量
9keys
查找所有符合给定模式 pattern 的 key , 比如说:
KEYS * 匹配数据库中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。
10SCAN  SSCAN HSCAN ZSCAN
11SORT
SORT today_cost ALPHA 按照字符排序
SORT uid get # get user_level_*  get user*
12FLUSHAL
13SWAPDB  0  1  数据库内容互换
自动过期
EXPIRE 过期时间   秒      
PEXPIRE mykey 1500  毫秒    
EXPIREAT   UNIX 时间戳  秒    
PEXPIREAT mykey 1555555555005  毫秒  
TTL   秒  PTTL 毫秒
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间。
TTL  waybill_999
PERSIST
移除给定 key 的生存时间,将这个 key 从“易失的”(带生存时间 key )转换成“持久的”(一个不带生存时间、永不过期的 key )。
PERSIST waybill_999
模式:导航会话
假设你有一项 web 服务,打算根据用户最近访问的 N 个页面来进行物品推荐,并且假设用户停止阅览超过 60 秒,那么就清空阅览记录(为了减少物品推荐的计算量,并且保持推荐物品的新鲜度)。
这些最近访问的页面记录,我们称之为『导航会话』(Navigation session),可以用 INCR 和 RPUSH 命令在 Redis 中实现它:每当用户阅览一个网页的时候,执行以下代码:
MULTI    
               RPUSH pagewviews.user:<userid> http://.....    
               EXPIRE pagewviews.user:<userid> 60
EXEC
如果用户停止阅览超过 60 秒,那么它的导航会话就会被清空,当用户重新开始阅览的时候,系统又会重新记录导航会话,继续进行物品推荐。
事务
MULTI
标记一个事务块的开始。
事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。
EXEC 执行所有事务块内的命令。
假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么 EXEC 命令只在这个(或这些) key 没有被其他命令所改动的情况下执行并生效,否则该事务被打断(abort)。
DISCARD 取消事务,放弃执行事务块内的所有命令。
如果正在使用 WATCH 命令监视某个(或某些) key,那么取消所有监视,等同于执行命令 UNWATCH 。
WATCH  
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
Lua脚本
持久化
SAVE 阻塞所有客户端,进行磁盘持久化操作
BGSAVE  异步持久化,fork一个子进程。
BGREWRITEAOF
执行一个 AOF文件 重写操作。重写会创建一个当前 AOF 文件的体积优化版本。
即使 BGREWRITEAOF 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 BGREWRITEAOF 成功之前不会被修改。
LASTSAVE
返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示。

发布与订阅
publish channel message
publish  chat_room  hello!
subscribe chat_room    //订阅该channel


RDB和AOF
RDB 的优点
RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。
RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
RDB 的缺点
如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。
每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。
AOF 的优点
使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。
AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
AOF 的缺点
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。 (举个例子,阻塞命令 BRPOPLPUSH source destination timeout 就曾经引起过这样的 bug 。) 测试套件里为这种情况添加了测试: 它们会自动生成随机的、复杂的数据集, 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。
Redis悲观锁和乐观锁
单客户端 单线程
多线程 客户端
客户端1
客户端2
Redis实现乐观锁(秒杀)



Jedis
Redis.conf 讲解
大小写不敏感


包含 配置文件


网络
通用 GENERAL

Bash

复制代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

daemonize no #守护进程 默认NO 开启 yes

pidfile /var/run/redis_6379.pid  #如果以守护进程运行需要指定pid文件

# 日志级别

# Specify the server verbosity level.

# This can be one of:

# debug (a lot of information, useful for development/testing)

# verbose (many rarely useful info, but not a mess like the debug level)

# notice (moderately verbose, what you want in production probably)

# warning (only very important / critical messages are logged)

loglevel notice  

logfile ""  #日志的文件名

databases 16  数据库数量

always-show-logo yes 显示Redis logo


快照 SNAPSHOTTING
.rdb .aof

Bash

复制代码

1

2

3

4

5

6

7

8

9

10

11

12

#   In the example below the behaviour will be to save:

#   after 900 sec (15 min) if at least 1 key changed

#   after 300 sec (5 min) if at least 10 keys changed

#   after 60 sec if at least 10000 keys changed


stop-writes-on-bgsave-error yes  #持久化出错是否继续工作


rdbcompression yes  #是否压缩rdb文件  消耗cpu资源


rdbchecksum yes  #保存rdb是否进行校验


dbfilename dump.rdb  #rdb文件保存的目录

主从复制 REPLICATION

安全 SECURITY

Bash

复制代码

1

2

3

config get requirepass   #获取redis密码

config set requirepass   "123456"  #设置redis密码

auth 123456  #使用密码认证登录

限制客户端 CLIENTS

Bash

复制代码

1

2

3

maxclients 10000  #最大客户端连接数

maxmemory <bytes> #最大内存数量

maxmemory-policy noeviction #内存满之后的拒绝策略


APPEND ONLY 模式

Bash

复制代码

1

2

3

4

5

6

appendonly no  #默认不开启AOF

appendfilename "appendonly.aof"  #持久化文件的名字

# appendfsync always   #每次修改都会同步 消耗性能

appendfsync everysec  #每秒都会同步可能会丢失1秒的数据

# appendfsync no      #不执行系统自己执行,速度最快


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
8月前
|
NoSQL Redis
06Redis - Redis的使用
06Redis - Redis的使用
38 0
|
9月前
|
存储 NoSQL 算法
|
9月前
|
NoSQL 安全 Redis
|
8月前
|
存储 NoSQL Linux
Redis之Redis为什么这么快解读
Redis之Redis为什么这么快解读
|
9月前
|
存储 NoSQL 中间件
redis
redis
36 0
|
9月前
|
监控 NoSQL Java
|
9月前
|
NoSQL Redis
|
10月前
|
存储 消息中间件 NoSQL
什么是Redis?
redis是一个高性能的key-value数据库。
53 0
|
11月前
|
NoSQL Redis 数据库
什么是Redis
Redis,即远程字典服务,是一个开源的使用ANSI C语言编写,支持网络,可基于内存亦可持久化的日志型,Key-Value数据库。类似于map
49 0
|
NoSQL Redis 流计算
使用redis
使用redis
63 0