redis的实际运用
key设计原则
- 把表名转换为key前缀 如, tag:
- 第2段放置用于区分区key的字段–对应mysql中的主键的列名,如userid
- 第3段放置主键值,如2,3,4…, a , b ,c
- 第4段,写要存储的列名
2 注意:
在关系型数据中,除主键外,还有可能其他列也步骤查询,
如上表中, username 也是极频繁查询的,往往这种列也是加了索引的.
key-value没有唯一索引和主键索引
redis不能通过非key查询 只能对要查询的字段进行数据冗余 (类似与关联表)
转换到k-v数据中,则也要相应的生成一条按照该列为主的key-value
Set user:username:lisi:uid 9 (这里username为key)
这样,我们可以根据username:lisi:uid ,查出userid=9, (过渡查询 获取id)
再查user:9:password/email … (再根据id 获取所有数据)
Redis数据库的应用
场景一:标签归类
如果使用mysql数据库,这样会涉及大量的连接查询
换成key-value存储
业务场景二 位图法统计活跃用户
有一亿用户,用户有频繁登录的,也有不经常登录的。
问题:
1.如何来记录用户的登录信息
2.如何查询活跃用户
业务场景三
关于王者荣耀战绩查询的实现(为什么会出现延时性的思考)
借助redis来实现存储和查询战绩信息
- 建立redis集群,master用来记录新的战绩记录,并使用aof来进行持久化
- clusters用来查询战绩信息,通过master传输的aof来进行同步
- master的aof传输可以使用aof重写功能,去掉中间过程
- 由于aof是有短暂间隔的所以战绩查询有一定延迟
业务场景四
仿微博(关注、发布动态)
关于用户登录(id name password)
关于用户key的设计(redis的key设计意义 等同于mysql表结构的设计)
用户登录
- 首先根据username 获取userid
- 再根据userid 获取password
发微博
粉丝关系(关注关系)
我的关注( 集合 following )
我的粉丝( 集合 followed )
使用2个集合用于统计关注和分数数量
增强cookie安全性(保证用户名及密码的安全性)
- 通过cookie保存密码的用户信息登录时 可以通过生成随机数作为用户令牌 并保存到redis服务器
- 用户免密登录时 获取用户令牌并与数据库进行对比 拦截非法用户访问
- 注销用户时 清空redis中的用户令牌
使用哈希数据存储微博
使用hash能够实现 key一对多
推送微博 VS 拉取微博
- 推送微博的模式 如果一个人有大量的粉丝,这样存在大规模的lpush recivepost:userid postid
并且一次推送要一次遍历千万个粉丝 - 有些用户时长期不在线 但微博本身是有时效性的 使用推送模式存在大量的推送行为没有实际意义。
- 使用用户登录拉取关注人的最新微博 最符合实际的业务需求
微博获取(通过主动拉取的)
通过链表 获取我的关注的人的微博
获取我的关注id smembers following:useid
根据 mystarid获取postid pullpost
使用sort 能够起到类似于mysql join(连接查询的作用)
问: 上次我拉取了 A->5,67,三条微博, 下次刷新home.php, 从>7的微博开始拉取
解决: 拉取时,设定一个lastpull时间点, 下次拉取时,取>lastpull的微博
JAVA VO (post集合,lastpullTime) 下一次获取只获取晚于该时间的微博。
问: 有很多关注人,如何取?
解决: 循环自己的关注列表,逐个取他们的新微博。
问: 取出来之后放在哪儿?
答: pull:$userid的链接里
问: 如果个人中心,只有前1000条
答: ltrim,只取前1000条
问: 如果我关注 A,B两人, 从2人中,各取3条最新信息,这3+3条信息, 从时间上,是交错的, 如何按时间排序?
我们发布时, 是发布的hash结构, 发布时间作为一个属性存在hash,不能按时间来排序.
解决方案:
同步时,取微博后,记录本次取的微博的最大id,
下次同步时,只取比最大id更大的微博。
结合Java的来实现最新的50条微博
- 使用一个链表 存放微博的id
- redis只使用存储频繁使用的数据,冷数据应存储到mysql数据库中
将一个用户的最新20条数据存储到redis,其他的存储到mysql数据库当中。 - 应用首先会在redis读取数据,如果没读取到,就会到mysql中获取