共计 1693 个字符,预计需要花费 5 分钟才能阅读完成。
前言
一款 app,音讯页面有:钱包告诉、最近访客等各种告诉类别,每个类别可能有新的告诉音讯,实现已读、未读性能,包含多少个未读,这个是怎么实现的呢?比方用户 A 拜访了用户 B 的主页,难道用 rabitmq 给 B 发告诉音讯吗?量大了老本受得了吗?有没有成本低的计划呢
小谈
挺好的一个问题,惋惜其余的答复要么是大而化之想当然,要么是顾左而言他,没有一个正经的答复。
这个是很常见的需要,在做这类需要的时候,首先要做的是,设计一个适合的业务模型,那么这个模型就是“对话模型”,
将问题中的 ” 设置 ”,“赚钱积分”,” 最近听众 ”,” 好友跟新 ”,” 最近来访 ” 当做一个“虚拟人”来解决,你跟 ” 虚拟人 ” 组成了一个 ” 对话列表(msg_group)”
“虚拟人”与正常人的区别就是,虚拟人与你的对话是单向的,只能他向你发消息,你无奈回复。
所有,判断有没有小红点,或者小红点的数字是多少,就是简略的获取你与虚拟人的对话的未读的音讯的数量。
“最近来访”标签
当有人拜访你主页的时候,后端会以这个“最近来访”虚拟人的身份给你发一条音讯,不过音讯里还有一个非凡标记,表明了起源。咱们除了要拉取总量,还有不同起源音讯的数量。当然,一个动作不肯定只发一条音讯,比方,图中下方有个金刚键 ” 音讯 ”,它是所有音讯的总和,所以,投递其余音讯的时候,也要给它投递一次,不过它只展现一个未读数字,所以这个音讯只须要一个 msg_id 即可,不须要音讯 payload。
前端怎么展现
看具体产品需要。
每个对话能够看作一个 msg_group,它是一个音讯的队列(留神,不是咱们常说的音讯队列), 每条 msg 的 msg_id 都是有序递增的,至于 msg_id 只是队列内有序还是全局有序,就看你抉择了, 个别数据 10 亿以内没必要优化,发号器全局有序即可。这个队列有根本的信息: 参加人(图中的例子只有 2 个,你和“虚拟人”),maximal_msg_id。
你只须要保留一个 last_pull_msg_id 或 last_read_msg_id 即可,在拉取信息的时候,带上这个 last_msg_id 即可。
当然,音讯列表的存储,读取,就比拟多样了。能够是 MySQL,nosql,hbase,redis。个别咱们是混合存储,特地老的存 hbase,比拟老的存 mysq 或 nosql,新数据存 redis。云厂商也有专门针对这类场景的存储产品。大多数状况,咱们只须要一个数量,固定从 maximal_id 往前取,如果取到 100 条还没完,间接返回 99+ 完事了。
实际上,图中的需要,比方“设置”,” 隐衷设置 ”,是整个产品全局的,所以能够弄个简略的 ” 播送音讯模式 ”,播送模式就是维持一个单向的音讯的队列,所有的人都能够拉取这个队列的音讯,只须要他们各位保护本人的 last_id 即可。
“已读和未读 “。它蕴含两层意思,一个 判否 ,即内容你是否读过,二是 计数,即这个内容有多少人读过。
长尾起因
如果你用 Redis 存储,老本十分高,节约十分重大。如果不必 redis,一旦刷到历史数据,会十分十分慢。在这里 bitmap 必定是搞不定的,因为 bitmao 须要加载全副数据,显然不可行。
这个时候,通常的策略是 ”[log record]” 和 ”comb”, 咱们每产生一个动作,比方读,赞,珍藏,就会产生一个 log record(取关,勾销赞 … 也是一条独立的 log record),咱们由专门的大数据系统对立收集这些 record,而后对多个维度的数据统计,将统计后果存起来,前端获取数据的时候,先从缓存取,取不到再到 comb 取。comb 的数据规模是远远小于 log record 的,查问速度十分快。
log record 因为不波及查问,所以没必要用数据库,个别间接存 hbase 或 cassandra 这类便宜存储介质。
热门内容
用户互动十分沉闷,所以在写入 log record 的时候,会间接同步更新缓存,然而缓存的数据并不保障非常精确,它只是蛊惑用户的,精确的数据是以 log record 为准的,你在 wb 常常能够看热门内容的点赞数跟理论的数量不符。因为 wb 的缓存,独立的 counter,理论的数据不同步。
本文由博客一文多发平台 OpenWrite 公布!