摘要.
# 14 个回答
默认排序
北京更美互动信息科技有限公司 后端工程师
5 人赞同了该回答
根据你所描述的场景,特定的场景应该选用更为合适的工具来解决问题;
mysql 如果按照 innodb 存储应该来说,它的优势在于提供了良好的事务管理、崩溃修复能力和并发控制。 缺点是其读写效率稍差,占用的数据空间相对比较大。
redis作为内存 key-value 数据库,支持多种数据结构;支持高并发,性能好。
目前你所遇到的问题:
- 大量的数据存储
- 游戏应用画像
- 数据模糊匹配
找到问题之后既可以对症下药,结合你自己的使用场景
推荐三个方案:
方案 1:用 es,(1)分布式的搜索引擎和数据分析引擎 (2)全文检索,结构化检索,数据分析
(3)对海量数据进行近实时的处理
方案 2:策略匹配部分做成后台任务这种,在 redis 维护各个维度的应用队列,然后用后台任务定时去更新队列,接口读取时候拿到队列前 10
方案 3:使用 redis 的有序集合
赞同 52 条评论
码农
不知道你所谓的匹配过程是什么样的,是单纯的 like 还是说类似把名称分词后找每个词的权重什么的。但大概看上去不管哪种如果是查询后直接对外输出感觉的确快不起来。
个人建议是这种情况下一个是考虑换存储,把这种磁盘存储换成内存存储,比如换成 es。另一个方面是考虑实际排名算法上是否有优化余地,把可能的字符串匹配换成 hash 后的分数比较。
深圳用友 CTO
1 人赞同了该回答
提前计算缓存就好了,推荐的游戏又不需要实时的计算。只要定时计算一次然后缓存十条数据就好,页面直接取缓存的十条数据
国际法定青年码农
1 人赞同了该回答
不用 redis,把数据同步到 elastic search 或者 solr,然后对游戏名字进行匹配度查询即可。
谢绝人生相谈及中文编程类问题
1 人赞同了该回答
相似度查询是 Elasticsearch 的特长。但 Elasticsearch 本身也有比较高的门槛和复杂度,如果要使用的话最好先做个技术预研。
如果访问热点比较集中的话,那么用缓存也是一个不错的办法。另外,游戏的名字一般不怎么变化,所以你们也可以考虑是否可以把结果预先算出来。
最后,网页打开慢说明你们应该用的是传统页面,可以考虑换成 Ajax 加载。这样虽然总体时间不变,但在心理层面有助于缓解用户的焦虑。
C++ 大师会惹争议,C++ 高手总是少不了的。游戏服务端。
需要分布,把游戏名,分布到几十个数据库实例 (物理机) 里,每个数据库分别处理一部分
然后结果汇总。
因为任何索引都不能有利于你这个匹配计算
匹配的过程是 O(N) 的
要优化响应速度就得分布式并行计算
最关键的一点,一旦计算过一个游戏的相关游戏以后,把结果缓存起来; 当新游戏出现以后,反过来修改相关它的那些游戏的相关列表。
有头发的程序猿
不会啊,上百万级的数据,查询起来,不会很卡的,更加不会导致网页打开慢。
因为游戏是响应可能需要毫秒,但是网页在 1S 之内打开,也是可以接受的,一般而言几百毫秒,是完全正常的一个打开速度。
你说的网页打开慢,应该就是几秒的时间,虽然 MYSQL 有几百万数据,也不至于响应时间变成几秒。
有可能是 SQL 语句的问题,或者索引。
理论来讲,优化数据库是首先的,因为这样比较简单,你使用 REDIS 作为缓存,你需要修改代码,还是测试,读写又变得麻烦了。
你可以尝试修改一下数据库的储存介质,如果你是使用啊里云的话,直接储存本地 SSD 上面,可以很大的 IOPS 提高。
IT
公司想在某款游戏页面,推荐名字最接近这款游戏的十款游戏,目前策略是匹配所有的游戏名字,给匹配度打分,取最高的十个,问题是 mysql 数据库中游戏这个表数据量极大,有上百万的游戏数据,查询起来特别费时间,导致网页打开慢,应该从哪方面优化呢?
根据你的需求来看,无论是直接从 mysql 查询,或者直接缓存到 redis 中,都不能直接解决问题。
因为 mysql 和 redis 都不太擅长解决匹配度的问题。用这两个工具当然会查询起来特别费时间。
推荐的解决方案:
1. 使用 Elasticsearch 。将这几百万数据写到 es 中,然后将游戏名字传入,通过 es 的相似度功能返回合适的结果。
2. 根据你的场景,如果 需要产生类似推荐的游戏本身数目不是特别大的话,可以考虑用 job 将这些结果跑出来,缓存到 redis 中。 在查询的时候,直接从 redis 中获取。
搜索关注微信公众号:【1024 笔记】,免费获取海量学习资源
根据你的描述个人建议使用缓存比较合理,因为这类的需求应该不需要实时的查询数据库数据,所以可以采用缓存,这样有数据的时候就取缓存,需要更新数据的时候再更新数据即可。
赞同添加评论
分享
收藏喜欢
继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续
说 solr ,elk 的都是扯淡,不可能为了一个功能再维护一套那么重的东西。这里只是需要一个倒排索引而已,可以使用 mysql 的全文索引,也可以自己通过 redis 简单实现一个倒排索引
赞同添加评论
分享
收藏喜欢
继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续
百度 架构师
好问题!稍微扩展一下,这个问题的背后代表着四类数据查询场景,以及对应的四类解决方案:本地缓存、redis 缓存、MySQL 索引、MySQL 从库
# 一:本地缓存
将查询结果缓存到 application server 的内存中,这个方案适用于查询结果集很小的的公共数据。
- 结果集很小意味着可以完全缓存到内存中
- 公共数据指跟特定用户无关的数据,比如楼主提到的最接近的十款游戏,其它的比如游戏排行榜、股票行情等。
本地缓存不依赖第三方中间件,改造成本低,查询速度快,这可能是最适合楼主题目要求的答案。
# 二:redis 缓存
适用于缓存规模较大的公共数据。
因为 redis 有集群,所以可以缓存较大规模的数据,几十到上百 GB 的 redis 缓存还是很常见的。
另外,现在也很多公司把 redis 当数据使用,存储用户的私人数据。特别是一些 PHP 类无原生常驻进程的项目,然而这可能需要承担一些数据丢失的风险,个人不是很推荐。
# 三:MySQL 索引
好的索引和 SQL 查询语句可以极大加速查询速度。在合理优化的情况下,4 核 8GB 的 MySQL 可承担单机 10000QPS 的查询,在很多情况下足以应对。
另外,合理的索引对 Update 数据也是必须的,因此也算是 MySQL 的基本功之一。
# 四:MySQL 主从
适用于 SQL 语句的查询结果多变无法缓存的情况。比如查询用户个人数据,将查询结果缓存到 redis 中可能并不会具备很高的缓存命中率。实际上,MySQL 在 5.x 版本中是存在查询缓存的,但从 8.0 开始就移除了。
这种情况下,比如单机查询性能无法满足需求,适当使用从库是一个可以考虑的方案。从库的问题是有可能必须在代码层面考虑主从同步延迟,在主库或从库有一方繁忙或网络延迟的情况下这有可能相当大(比如几小时)。
赞同添加评论
分享
收藏喜欢
收起
继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续
PHP 是世界上最好的语言
如果是单体服务,直接内存里做缓存,没有网络开销,速度杠杠的。如果是集群,elasticsearch 吧,强过 redis
赞同添加评论
分享
收藏喜欢
继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续
外汇交易员 宏观观察者
这个不需要实时匹配吧?提前把结果表洗出来就好了。
go on
elk 好像能满足你的需求
赞同添加评论
分享
收藏喜欢
继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续
写回答
相关问题
让 redis 充当 mysql 缓存的时候如何缓存 mysql 的数据关系? 9 个回答
先更新 mysql 数据库后更新 redis 缓存这一缓存更新策略可行吗,有什么问题? 7 个回答
redis 为什么是 key,value 的,为什么不支持 sql? 16 个回答
mysql in 查询优化, 如何提高查询的速度, 百万级的 mysql 数据库? 6 个回答
Redis 可以用来做数据库吗? 47 个回答