前言
目前大部分程序员,在使用redis的过程中,基本都存在或多或少的滥用。其中包括key的命名,失效时间,key的存储结构都非常随意。项目上线后,短短时间内 内存水涨船高。我决定将我个人设计redis的习惯分享给各位(有不对,不合理的地方希望可以谅解)我将会在以下几个方面进行说明
- key 命名设计
- key 常见业务场景
- php 命令使用场景
- key 过期时间设置
- redis连接池
一、key命名设计
可读性和管理性
以项目名为前缀(防止key冲突),用冒号分隔,比如项目名:表名:id
zh(知乎):news_data(新闻数据):2(主键id)
zh:news_data:2
精简性
key的命名,尽量精简,key的名字长度对内存的占用不可忽视,我们来实际操作看看
//特地搞个长一点的key 方便看对比
SET zh:news_data_test_info:2 1
SET zh:n_d:2 1
我们现在分别set了两个key,结构都是string,值都是1。我们来看看两个key 对内存对占用情况

通过上图我相信各位看官都已经明白为什么key要精简了
二、key 常见业务场景
XX列表。如:新闻列表,用户收支记录,帖子列表等。。。
以下我们用新闻来举例, 假设 产品经理给了我们一个这样的需求:
首页新闻列表(页面展示数据:标题,文章摘要,发布时间,作者。业务约束:按发布时间倒序,每次下列加载20条)
首先我们需要先设计一个key,去存储关于新闻的基本数据(Hash结构,为什么用Hash?这里就不赘述了详细可以看教程,结合简介性去搞明白redis的几种存储数据结构 Redis菜鸟教程)
HMSET zh:news_data:1 id 1 title "文章标题1" synopsis "文章摘要1" author "Icecream" create_time "1594794254"
HMSET zh:news_data:2 id 2 title "文章标题2" synopsis "文章摘要2" author "Icecream" create_time "1594796254"


接着我们需要设计一个列表(zset)有序集合可以满足各种上述需求的排序,具体可以看这篇文章了解zset菜鸟教程
ZADD zh:news_list 1594794254 1(新闻主键id)
ZADD zh:news_list 1594796254 2
如果仅仅只是按时间倒序,我们score值有必要存时间戳吗?存主键id不是更好吗?
ZADD zh:news_list2 1 1
ZADD zh:news_list2 2 2

同样是完成了业务,存储主键ID 可以节省8Bytes不香吗?后续如果衍生需求 用户发布新闻列表 socre保持不变继续存新闻主键id,value改为用户主键。这样一个key就能满足两个需求,岂不美哉?
数据统计,如:每日活跃用户,每日新增用户等
此处用每日活跃用户举例,首页用户的活跃时间对我们统计来讲没有太大的价值,活跃用户我们是需要去重的,这里我们就可以使用redis中的set结构了。set结构中成员是不可重复的。我们只需要在用户登陆的时候,将用户uid插入key 即可
//登陆成功~~
SADD zh:hot_user:0715 1
SADD zh:hot_user:0715 1
SADD zh:hot_user:0715 1
SADD zh:hot_user:0715 2
SADD zh:hot_user:0715 3
SADD zh:hot_user:0715 4
SADD zh:hot_user:0715 5
//统计活跃用户
SCARD zh:hot_user:0715
(integer) 5 //今日活跃的用户为5名哦~

上述的做法从业务逻辑来讲其实没啥毛病,但程序员就应该更加精益求精,要有极客精神嘛。偶然间我看到了这篇文章 redis的bitmap使用场景。根据这篇文章讲解的bitmap 我决定实际操作试试
//登陆成功~~
SETBIT zh:hot_user2:0715 1 1
SETBIT zh:hot_user2:0715 2 1
SETBIT zh:hot_user2:0715 3 1
SETBIT zh:hot_user2:0715 4 1
SETBIT zh:hot_user2:0715 5 1
BITCOUNT zh:hot_user2:0715
(integer) 5

set与bitmap的存储对比,少了将近10Bytes 香吗?真香
呃,剩下的有时间再写了