惊了 redis 还能这样玩??

2018-05-07 18:39:19 +08:00
 johnsneakers
接手新项目,那个程序把 hash 当 MySQL 来用,给我说他们以前项目都这样搞。具体是:所有玩家的个人信息放在 user 这个 key 里面,hset user 10000 用户个人信息 json。 第一次见这样玩的 ,我太菜了,怎么给对方说都不听。
19340 次点击
所在节点    Redis
111 条回复
darklowly
2018-05-08 11:12:41 +08:00
同时注意几点

1 搞程序的严谨一点, 不要觉得自己没见过的,就不合理,就要喷一下。
2 适当的调查一下,或搜索一下就能解决的问题,不要拿来喷
3 标题党太严重,还是你自己真的十分大惊小怪?
youxiachai
2018-05-08 11:19:54 +08:00
@darklowly 我觉得..应该是真的没见识过的吧...
毕竟 lz 还尝试.说服对方...
bk201
2018-05-08 11:22:30 +08:00
hash 只会在额定的要求范围内,才会以 ziplist 存储,当超过额定阈值后会转换成真正 hashtable 格式并重新存储。而 hashtable 的存储对于内存的使用不占优势
==
你是说这个问题嘛
johnsneakers
2018-05-08 11:25:48 +08:00
@darklowly
1. 你还挺会扣帽子的,我哪里喷了。不合理的设计提出来说怎么了?
2. 论坛不是讨论技术的地方? 设计上的东西发论坛来讨论怎么了? 又是一顶帽子?
3. 标题党? 我确实很惊讶。

你的分析也很有意思, 拿多个 key 存储方案和一个 key 存储方案来比容量。
johnsneakers
2018-05-08 11:27:21 +08:00
@youxiachai 确实没见识过,所以发到论坛求教一下
perssy
2018-05-08 11:28:18 +08:00
@youxiachai 这篇文章里写的也不是把所有 key 都放一个 hash 里吧,而是每个 hash 存 1000 条数据,超过这个数字的话 HSET 会有明显的 cpu 占用
gouchaoer
2018-05-08 11:31:11 +08:00
我觉得 LZ 说的没错啊,redis 本质上是一个缓存,数据落地到数据库是理所当然的啊
最重要的是如果用户信息存到 redis 里面了,那么你只能根据用户 id 去存取而无法做查询操作,比如你要查询哪些用户今天登录过,redis 没法查询哦

另外推荐 mongo 的,这个场景有意义么?
hyq
2018-05-08 11:41:55 +08:00
即使楼主 append 了一下,还是有不少人没看明白。
liu7833
2018-05-08 11:45:51 +08:00
一个 hash key 存的话肯定是有问题的,容易造成 key 的热点,最终打垮一个节点
troywinter
2018-05-08 11:53:22 +08:00
那些说放到 hash 里合理的,你们写个性能测试看看,不用说千万并发,就 10 万的并发,你们看看 redis 的性能
caixiexin
2018-05-08 11:53:30 +08:00
大 key 在 Redis 集群里是个隐患
ytmsdy
2018-05-08 11:59:54 +08:00
结合具体的业务实际情况吧,如果业务上对用户信息需要高频读写,那这么搞也算是情有可原。
但是想了一圈,想不出来能有什么业务需要对用户信息高频读写的。
打个比方
Redis 类似于微粒贷,花呗等短期的消费贷款
mysql 类似于房贷
偶尔手头紧,来点消费贷缓解燃眉之急,没问题。
但是要是拿着消费贷去买房子那就有点嘬死了
Waterchestnut
2018-05-08 12:01:42 +08:00
这种会有热 key 问题,节点会瘫痪,会报出 too many cluster redirections。。。。血的教训啊
enenaaa
2018-05-08 12:04:59 +08:00
从主楼内容看,楼主语文堪忧
ty89
2018-05-08 12:11:07 +08:00
@ytmsdy 游戏业务里对用户数据读写操作是很频繁的,比如战斗中计算战力值,经验点数的增加减少,装备对战力的加成影响等等,一堆高频读写。


楼主少见多怪且蜜汁自信,新人总是会认为老项目里各种做法不合理,直到自己掉进坑里了才会发现原来这么做都是有原因的。
darklowly
2018-05-08 12:14:04 +08:00
@johnsneakers


第一

你的原话是( 第一次见这样玩的 ,我太菜了,怎么给对方说都不听)。

注意这里的措辞

第一次见这样玩的
我太菜了
怎么给对方说都不听。

就算不是喷?也带着极大的负面情绪。

第二

技术类的问题,网络上有很多的资料,如果自己没见过的,不懂的,第一反应,应该是查资料,而不是惊叹,也不是到论坛上讨论。在你把所面对的技术问题本身搞清楚了,再来讨论比较好。附赠一篇文章给你( https://blog.csdn.net/danky/article/details/1370632

第三

在 redis 里面,本身就是一个大的 hashmap,然后 hashmap 包含很多的 key==>val,同时这里的 val 可能有多种类型。当 val 是 hashmap 的时候,他的数据结构本身和 redis 的大 haspmap,并没有太大的不同。

获取一条数据的流程大概是:
1 从大的 hashmap 拿到 user 集合的小 hashmap O(1)级别
2 从小的 hashmap 拿到 user 的信息 O(1)级别

你的想法是一步就能拿到的,为什么要两步? 性能损失了 50%?其实完整的过程是:
1 发送命令给 redis
2 从大的 hashmap 拿到 user 集合的小 hashmap O(1)级别
3 从小的 hashmap 拿到 user 的信息 O(1)级别
4 返回数据
2 和 3 都是 O(1)级别, 相比 1 和 4 的时间,可能 5%都不到。那么性能是微乎其微的。

第四

我并不是倾向于把所有用户放到一个 key 里面,也不倾向于一定要分开放,具体问题具体分析。我只是想说两种方案都可以。
clippit
2018-05-08 12:18:43 +08:00
可以参考一下 https://redis.io/topics/memory-optimization
用 hash 存一堆 k-v 的用户信息是可以节约内存的,但是单个 hash 不能太大,需要手动分一分
youxiachai
2018-05-08 12:24:36 +08:00
@perssy 那文章是 3 亿用户.....
这里是个实践问题....而已
youxiachai
2018-05-08 12:26:25 +08:00
@perssy 打错是 3 亿图片信息...
ety001
2018-05-08 12:26:36 +08:00
我觉得得先把语文学好,完全没有看懂说的是什么意思。。。

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

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

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

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

© 2021 V2EX