Redis的基本键值API使用、内部编码、使用场景讲解

一、Redis的启动、配置、命令行操作和关闭

1.启动Redis:默认配置 + 运行配置 + 配置文件启动

默认配置:redis-server

运行配置:redis--server --configKey1 configValue1 --configKey2 configValue2

配置文件启动:redis-server /root/yangf/redis-4.0.6/redis.conf

生产环境中建议使用第三种启动。

2.Redis连接与命令行操作

交互式方式:redis-cli -h {host} -p {port}

命令行方式:redis-cli -h {host} -p {port} {command}

3.停止Redis服务

基本命令:redis-cli shutdown

采用kill:kill redis进程     ---但是不能采用kill -9 redis进程

二、对键的基本操作命令讲解

1.查看所有的键                    keys *

2.键总数                               dbsize

3.检查键是否存在                 exists key

4.删除键                                del key [key ...]

5.键过期                                expire key seconds

                                              expireat key timestamp    (2018.09.18 10:10:10--1537150210000)

                                              pexpire key milliseconds

                                              pexpireat key milliseconds-timestamp     (毫秒级在redis2.6后提供)

  清除键的过期时间               persist key

                                              ①若key不存在,返回结果0;

                                              ②若过期时间为负值,则相当于del命令;

                                              ③执行set命令会去掉过期时间,研发时需要特别注意;

                                              ④redis不支持二级数据结构的内部元素过期功能;

                                              ⑤setex == set expire ,原子执行,减少网络通讯时间。

6.查看键剩余时间                  ttl key

                                              pttl key

                                              ≥0:剩余的过期时间;-1:未设置过期时间;-2:键不存在。

7.查看键的数据结构类型       type key

8.键重命名                            rename key newkey

                                             renamenx key newkey

                                            ①若newkey已经存在,rename会将其覆盖,建议用rnamenx!

                                            ②重命名期间底层会执行del命令,若键对应的值比较大,有可能能会造成堵塞。

9.随机返回一个键                 randomkey

10迁移键                              ①move key db  --用于数据库内部,生产环境不建议

                                             ②dump key

                                                restore key ttl value

                                                 --redis实例之间,非原子性,不支持多个键

                                              ③migrate host port  key|”” destination-db timeout [copy] [replace] [keys key [key ...]]

                                                 --redis实例之间,原子性,支持多个键                         

11. 全量遍历键                     keys pattern

                                            ①pattern支持glob风格通配符;

                                            ②想删除所有以video字符串开头的键 redis-cli keys video* | xargs redis-cli del

12.渐进式遍历键                  scan cursor [match pattern] [count number]

                                             ①解决面向哈希、集合、有序集合的扫描命令  hgetall -- hscan  smembers -- sscan zrange -- zscan

                                              ②可解决keys命令产生的堵塞问题,但不能保证完整遍历所有键,具体开发时需要考虑情况。

三、对值的基本操作命令讲解

实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,redis会在合适的场景选择合适的编码,通过object encoding查看内部编码,这样做有两个好处:①可以改进内部编码,可保证对外的数据结构和命令没有影响;②多种内部编码实现可以在不同场景下发挥各自优势。

         

1.字符串数据结构讲解

字符串类型的值实际上可以是字符串(简单字符串+复杂字符串JSON、XML等)、数字、甚至是二进制(图片、音频、视频),但是值不能超过512MB。

基本命令

设置值             set key value [ex seconds] [px milliseconds] [nx|xx]

                          --ex与px都是用来设置过期时间的,代表秒级和毫秒级

                          --nx 键必须不存在,用于添加

                          --xx 键必须存在,用于更新

                          setex key seconds value  ==  set key value nx     可作为分布式锁的实现方案

                          setnx key value == set key value xx

获取值             get key         --键不存在返回nil

批量设置值      mset key value [key value ...]

批量获取值      mget key [key ...]

计数                 incr key

                          decr key

                          decrby key increment

                          incrby key increment

                          incrbyfloat key increment

                          --值不是整数,返回错误

                          --键不存在,按照值为0处理

追加值             append key value

字符串长度      strlen key      (中文占用3字节)

设置并返回原值                  getset key value

设置指定位置字符              setrange key offset value

获取部分字符串                  get key start end

内部编码

int :8个字节的长整形          set key 8653 + object encoding key

embstr:39个字节的字符串  set key hello,zters! + object encoding  key

raw:>39个字节的字符串  

使用场景

缓存功能:(防止键冲突和有助可维护性,推荐使用 业务名:对象名:id:[属性])

public UserInfo getUserInfo(long id)
{
	String userRedisKey = "user:info:" + id;
	Object value = redis.get(userRedisKey);
	UserInfo userInfo;
	if(null != value)
	{
		userInfo = deserialize(value);
	}
	else
	{
		userInfo = mysql.get(id);
		if(null != userInfo )
		{
			redis.setex(userRedisKey, 3600, serialize(userInfo ));
		}
	}
	return userInfo ;
}

计数:(视频播放数等)

public long incrVideoCounter(long id)
{
	String key = "video:playCount:" + id;
	return redis.incr(key);
}

共享session;

短信验证码限速(限制一个IP地址不能在一秒内访问n次)

String phoneNum = "18252060161";
String key = "shoortMsg:limit:" + phoneNum;
Object isExists = redis.set(key, 1, "ex 60", "nx");
if(null != isExists || redis.incr(key) <= 5)
{
	//通过
}
else
{
	//不通过
}

2.哈希数据结构讲解

哈希类型键值本身又是一个键值对结构。

基本命令

设置值                                              hset key field value    (有类似hsetnx命令,和前面的功能一样)

获取值                                              hget ket field

删除field                                           hdel key field [field...]

计算field 个数                                   hlen key

批量设置或获取field-value               hmget key field [field ...]

                                                           hmset key field value [field value ...]

判断field是否存在                             hexists key field

获取所有field                                    hkeys key

获取所有value                                  hvals key

获取所有field-value                          hgetall key

                                                           --使用hgetall时,若哈希元素过多,有堵塞可能

                                                           --若只获取部分field,可使用hmget

计数                                                  hincrby key field

                                                           hincrbyfloat key field

计算value长度                                  hstrlen key field

内部编码

ziplist(压缩列表) :哈希元素个数<512&&值都<64, 节省内存;

hashtable(哈希表):不满足ziplist条件。

使用场景

关系型数据库数据转换为redis数据库,比如缓存用户信息

public UserInfo getUserInfoByDB(long id)
{
	String userRedisKey = "user:info:" + id;
	Map userInfoMap = redis.hgetAll(userRedisKey);
	UserInfo userInfo;
	if(null != userInfoMap)
	{
		userInfo = transferMapToUserInfo(userInfoMap);
	}
	else
	{
		userInfo = mysql.get(id);
		if(null != userInfo )
		{
	        redis.hmset(userRedisKey,transferMapToUserInfo(userInfoMap));
			redis.expire(userRedisKey, 3600);
		}
	}
	return userInfo ;
}  

3.列表数据结构讲解

一个列表最多可以存储2^{32}-1个元素,对两端可以插入和弹出,可充当栈和队列。

基本命令

右边插入                       rpush key value [value ...]

左边插入                       lpush key value [value ...]

某处插入                       linsert key before|after pivot value

查找                              lrange key start end        (0N-1)

获取指定下标元素         lindex key index

获取列表长度                llen key  

从右侧弹出                    rpop key

从左侧弹出                    lpop key

删除指定元素                 lrem key count value

                                        --count>0,从左到右删除最多count个元素;

                                        --count<0,从右到左删除最多count个元素;

                                        --count=0,删除所有元素;

按照范围截取列表         ltrim key start end

修改指定下标的元素     lset key index newValue

堵塞操作                       blpop key [key ...] timeout

                                        brpop key [key ...] timeout

内部操作

ziplist(压缩列表) :列表元素个数<512&&值都<64, 节省内存;

linkedlist(链表):不满足ziplist(压缩列表)时。

使用场景

消息队列:使用lpush+brpop组合实现;

     

文章列表:每个用户有自己的文章列表,分页展示文章列表

每篇文章使用哈希结构存储

hmset article:1 title xx timstamp 1476536196 content xxxx

.......

hmset article:n title xx timstamp 1476539638 content xxxx

向用户文章列表添加文章

lpush user:1:articles article:1 article:3 article:16

.....

lpush user:k:articles article:45 article:85 article:92

分页获取用户文章列表

articles = lrange user:1:articles 0 9

for article in {articles}

                hgetall {article}

4.集合数据结构讲解

集合中不允许有重复元素,且集合元素无序,最多可以存储2^{32} -1个元素,支持集合内的增删改查,还支持集合间交并差。

基本命令

集合内增删改查:

添加元素                                   sadd  key element [element ...]

删除元素                                   srem  key element [element ...]

计算元素个数                            scard key

判断元素是否在集合中              sismember key element

随机从集合返回指定个数元素   srandommenber key [count]    count默认为1

从集合中随机弹出元素              spop key       --注意这个操作后,随机弹出的元素将被删除

获取所有元素                 smembers key

集合间交并差:

多个集合的交集               sinter key [key ...]

多个集合并集                   sunion key [key ...]

多个集合差集                   sdiff key [key ...]

将交集结果保存               sinterstore destination key [key ...]

将并集结果保存               sunionstore destination key [key ...]

将差集结果保存               sdiffstore destination key [key ...]

内部编码

intset(整数集合):元素都是整数且元素个数<512,减少内存使用;

hashtable(哈希表):不满足intset条件。

使用场景

典型就是标签,举例一个用户可能对娱乐、体育比较感兴趣,另一个可能对历史、新闻比较感兴趣,这些兴趣点就是标签,以此可以得到喜欢同一个标签的人,以及用户共同喜欢的标签,对于增强用户体验和用户粘度比较重要。

a 给用户添加标签

  sadd user:1:tags tag1 tag2 tag3 tag5 tag7 tag8

  sadd user:2:tags tag3 tag6 tag9 tag10 tag12 tag15

   .....

  sadd user:k:tags tag2 tag4 tag6 tag8 tag10 tag17

   .....

b 给标签添加用户

  sadd tag1:users user:1 user:3

  sadd tag2:users user:1 user:3 user:5 user:8 user:12 user:k

  .....

  sadd tagk:users user:3 user:7 user:21 user:35

   .....

c 删除用户下的标签

  srem user:1:tags tag1 tag5

   .....

d 删除标签下的用户

  srem tag1:users user:1

  srem tag5:users user:5 user:9 user:8 user:15 user:56

  .....

  注:c和d要放在一个事物里面执行

e 计算用户共同感兴趣的标签

  sinter user:1:tags user:3:tags user:5:tags user:7:tags

其他通用场景

spop/srandomember = random item (生成随机数,不如抽奖)

sadd + sinter = social graph(社交需求)

5.有序集合数据结构讲解

有序集合保留了集合不能有重复元素的特性,但元素可以排序,其为每个元素设置了一个分数作为排序依据,支持集合内的增删改查,还支持集合间交并差。

基本命令

集合内增删改查:

添加元素                                  zadd key score meneber [score meneber ...]

                                                   ---redis3.2为zadd添加了nx/xx/ch/incr

                                                   ---nx  member必须不存在,用于添加

                                                   ---xx  member必须存在,用于更新

                                                   ---ch  返回此次操作后元素和个数发生变化的个数

                                                   ---incr  对score做增加

计算成员个数                           zcard key

计算某个成员的分数                zscore key menber

计算成员排名                           zrank key member    

                                                   zrevrank key member

                                                    --zrank分数从低到高,zrevrank 反之;

                                                    --排名从0开始计算。

删除成员                                   zrem key menber [member ...]

增加成员个数                            zincrby key increment member

返回指定排名范围的成员          zrange key start end [withscores]

                                                    zrevrange key start end [withscores]

返回指定分数范围的成员          zrangebyscore key min max [withscores] [limit offset count]

                                                    zrevrangebyscore key min max [withscores] [limit offset count]

返回指定分数范围成员个数      zcount key min max

删除指定排名内的升序元素      zremrangebyrank key start end

删除指定分数范围的成员          zremrangebyscore key min max

集合间交并差:

交集                      zinterstore destination numkeys  key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

并集                      zunionstore destination numkeys  key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

内部编码

ziplist(压缩列表) :有序集合元素个数<512&&值都<64, 节省内存;

skiplist(跳跃表):不满足ziplist(压缩列表)时。

使用场景

典型的就是排行榜系统。举例视频网站需要对用户上传的视频做排行榜,榜单的维度可以使多面的:按照时间、按照播放数量、按照获得的赞数。

a 添加用户赞数

zadd user:ranking:2018-09-18 666 zyf

若再次获赞

zincrby user:ranking:2018-09-18 1 zyf

b 取消用户的赞数

  zrem user:ranking:2018-09-18 zyf

c 展示获取赞数最多的十个用户

  zrevrangebyrank user:ranking:2018-09-18 0 9

d 展示用户信息以及用户分数

  hgetall user:info:zyf

  zscore user:ranking:2018-09-18 zyf

  zrank user:ranking:2018-09-18 zyf

 

发布了52 篇原创文章 · 获赞 15 · 访问量 133万+

猜你喜欢

转载自blog.csdn.net/xiaofeng10330111/article/details/86596105