请支招: redis || mysql 评论,赞,星标,这些互动数据

2015-05-06 08:38:34 +08:00
 whatisnew

最近遇上评论数据的瓶颈了,放 mysql 吧受不了这么大的请求量,放 redis 吧,内存受不了。

mysql 请求太多,继续用的话只能再堆服务器了

redis 吧,数据太多了,比如:评论数据item_comment:item_id 去存取数据的话,那么现在的 item 已经到6位数了。。。那么也就是说 redis 里有 item_comment:654321(n) 仅仅评论数据就有 6 位数的 key 了,那么加上所有的互动就有 5*654,321 位数的 key,还是继续增加中。。。内存就。。。。

有什么好办法。。。

8821 次点击
所在节点    Redis
61 条回复
justfly
2015-05-06 09:56:17 +08:00
给个思路 mysql里面放评论的详细信息 redis里面只存放 ID 查询的时候先查redis得到ID 再从mysql里面拿详细信息组合 mysql上面可以放一层memcache或者redis 固定内存大小 做缓存 存放热数据
tonghuashuai
2015-05-06 10:19:19 +08:00
如果是我我会这么做:
评论内容放在 mysql,评论关联,赞,星标放到 redis
tonghuashuai
2015-05-06 10:29:20 +08:00
抱歉,上一条回错了,没有看全就回了。。。
tonghuashuai
2015-05-06 10:40:24 +08:00
我会这么做:
* 评论内容存到 mysql 中,比如 comment_id, txt
* 评论的关联存在 redis 中,用 zset(score为评论时间戳方便排序),sadd item_comment:item_id score comment_id
也就是 redis 中只有 id,都是 int 占用应该不会太过分吧,查询时查 redis 获取某个文章的评论id及排序,然后根据查到的 id 去 mysql 中查评论内容 (建好索引什么的应该不会慢吧)。
如果 id 增长很快的话可以用上面说的做一下 base64或MD5 就定长了
这样的话,只有有评论的文章才会在 redis 中有记录。

星标和攒就类似了,只有 id 关联,全在 redis 中,可以参考新浪微博的关注的实现。
cfan8
2015-05-06 10:52:42 +08:00
评论数据直接和item meta info压在一起吧,既然上NoSQL也没必要考虑什么范式之类的东西了
guoer
2015-05-06 11:16:01 +08:00
http://opentalk.upyun.com/show/issue/15
这里面洪小军的演讲可能对你有帮助
fuxkcsdn
2015-05-06 11:20:32 +08:00
把最近1礼拜的评论存放在 redis 上,其余的存在 mysql 里,1礼拜前的老帖本来看的人就少(你去试试要翻 cnbeta 1礼拜前的贴要翻几页就知道了)

代码里也就多一个判断
$comment = hGetAll('item_comment:65442345');
if(count($comment) === 0) {
$comment = $pdo->query('select * from t_comment where id=65442345');
}
yuankui
2015-05-06 11:29:42 +08:00
yuankui
2015-05-06 11:31:38 +08:00
评论的化,放 mysql,加上索引,性能问题应该不大吧,而且,可以加缓存啊.
fenzlie
2015-05-06 12:13:59 +08:00
为了回答这个问题特意去注册了一个帐号,结果发现还得等7000秒才能回复...

首先,如果你的系统还没有一个DAL层,那么是时候去实现一个了。否则下面的内容也没必要看了。

短期解决方案,你的MYSQL使用肯定有问题,不到百万级的数据不太可能搞不定。从表结构,语句,配置,连接池等等方面入手优化。就算你的业务再复杂,应该也可以应付得来。如果实在不行,必须要用REDIS,那就自己写一个一致性HASH,REDIS设置成多节点负载。这个实现快,也十分有效果,从KEY的数量上来看,区区65万X5也不算很大。 我之前记得100万KEY在REDIS中使用的内存也不过70M这样而已,当然,这和存的VALUE也有关系。现在商用服务器随便32G 64G内存,对数据结构做一些优化,REDIS也作一些优化BLABLA,用REDIS存储完全没有压力。注意这个阶段因为是对REDIS直接当数据库用的,所以要特别注意它的数据持久化和恢复方案。

如果从预期上来看数据会随业务发展有暴发式增长的话,那就需要考虑冷热数据交替的架构,简单讲就是加缓存结构,其它分库分表之类的就不提了。 可以把上述短期解决方案中的REDIS集群直接用做缓存,不会改变的冷数据扔到MYSQL数据库中去。请求先到缓存层,取不到再到数据库去取,同时把数据放置在REDIS中。这里大概的实现可以这样做,所有在REDIS中的数据全都设置相应的过期时间,每次访问重置过期时间。在每个REDIS MASTER节点拖的SLAVE节点上作RDB,把生成的RDB文件离线定时解析,把其中过期时间小于某值的所有数据同步到MYSQL中。

终极解决方案,如果你的数据量和访问量大到没边了。以上的REDIS集群不管怎么扩容,连正常的查询修改操作也完全COVER不住时。首先要恭喜你的应用比较牛B了现在。现在要做的事情有很多,可能需要有多级缓存,CDN扩展,甚至业务上要作一些妥协等等。从框架上来讲,大概的思路就是读写分离以及深化分离。 比如说,你前两步做的REDIS集群只用作读操作了,所有写操作只记录在简要日志中。写操作的请求过程中,不在数据持久层或缓存层作修改操作。然后你有离线的系统TAIL所有写操作的简要日志,把这些操作离线同步到数据持久层和缓存层。不过这样写操作因为只是记录了日志,写操作完成后有一段时间查询请求过来时是访问不到该修改的。这段时间的长短与你的离线日志流处理系统的性能相关。

REDIS 的RDB解析可以用REDIS RDB TOOLS, 用PYTHON写的,对过期时间的处理可能需要一些自定义的修改,PYTHON新手就可以胜任。
日志流的处理可以用卡夫卡,可靠,安全,速度快。
li24361
2015-05-06 12:19:27 +08:00
@fenzlie 讲得很好啊
sunchen
2015-05-06 12:21:46 +08:00
试试aerospike,使用ssd
keakon
2015-05-06 12:32:34 +08:00
粗略看了下,只有 @xiaozi 说的是能快速有效解决的,很多人不用勉强答的…
zyue
2015-05-06 12:36:14 +08:00
@fenzlie 赞一个 讲的很好
daoluan
2015-05-06 13:01:45 +08:00
只缓存热数据,数据库做分表/库,redis 没有你想的那么弱。
phx13ye
2015-05-06 13:13:28 +08:00
@fenzlie
没有体验过这种场景,有专门讲方面的书吗???
jevonszmx
2015-05-06 13:47:25 +08:00
@fuxkcsdn

hgetall,时间复杂度是O(N),会死的很惨,慎用。



应该分几个方面处理啊:
1、分析用户常见浏览量,如果大多数浏览量都是最近N条,则做评论翻页功能,最新N条是热数据,存redis,其他可以使用mysql做被动缓存;

2、评论分页使用前端缓存,如varnish,这样可以大大减轻后端压力;

3、mysql数据分表;

4、redis拆分实例,我们是程序实现了一个redis切片集群,通过key名hash切分到不同的redis实例;
wys163
2015-05-06 14:21:25 +08:00
mongodb 拯救你
fenzlie
2015-05-06 15:42:00 +08:00
@phx13ye 倒是没有留意过专门写这种场景的书。我是这样的来的,先了解一些分布式系统的基础知识,再找一些淘宝,京东,新浪微博等相关的讲座或说明去了解下。参加一些技术分享会,理解一些分布式相关的开源项目实现,比如说ZOOKEEPER,SPARK等。主要是理解这些公司分别应对的是什么样的问题,再去比较它们之间相似系统的实现差别。当然,最好是能进入有大流量公司的研发部门,这样直接干这一行最有效。

这些问题大多是有些难度,又十分有意思,实现了又很有成就感的。比如说淘宝双11时在一个电视上实时的秒级同步显示当前各地区交易总量,交易总额。这个东西正常人都知道肯定不可能是每秒执行一个SQL去数据库里查出来的。
hanwujibaby
2015-05-06 18:34:22 +08:00
没有必要把所有的值放到缓存里。热数据放到缓存中,每次写的时候同步更新缓存的失效时间。redis活memcache有自己的缓存失效算法的。如果用redis的话, 注意redis的slave.不然主挂掉的话,缓存雪崩很麻烦。大并发下能直接压死mysql.大数据的话注意一下分表和分库。这些基本的策略能扛住日均1亿的访问。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/188786

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX