【问题标题】:Can redis improve my MySQL performance and how to store data in redis similar to a DB table?redis 可以提高我的 MySQL 性能以及如何将数据存储在类似于 DB 表的 redis 中?
【发布时间】:2016-02-09 21:10:37
【问题描述】:

我有以下网站:

用户输入一些数据,服务器根据这些数据生成大量结果,这些结果需要显示给用户。我正在使用 php 计算数据,将其存储在 MySQL DB 中,并通过服务器端处理将其显示在 Datatables 中。 数据需要在有限的时间内保存 - 每隔一小时,整个表都会被删除并重新创建。

观察到的最大负载为:每天 7000 个会话/用户,一次最多 400 个用户。每小时我们在主表中插入超过 5000 万条记录。我们正在使用配备 Intel i7 和 24GB 内存、HDD 磁盘的专用服务器。

问题是当更多的人(一次> 100人)使用该站点时,MySQL无法处理负载并且MySQL+硬盘成为瓶颈。即使有几千个结果,用户也必须等待几分钟。磁盘是 HDD,目前没有放置 SSD 的选项。

问题:

  1. 用 Redis 代替 MySQL 能提高性能吗?

  2. 如何将生成的数据存储在 redis 中,以便我可以为 1 个用户检索它并按任何值对其进行排序并过滤它?

我在php中有以下数据

$user_data = array (
   array("id"=>1, "session"="3124", "set"=>"set1", "int1"=>1, "int2"=>11, "int3"=>111, "int4"=>1111),
   array("id"=>2, "session"="1287", "set"=>"set2", "int1"=>2, "int2"=>22, "int3"=>222, "int4"=>2222)...
)

$user_data 可以是长度从 1 到 1-2 百万的数组(我正在计算它并以 10000 的块插入数据库)

我需要在 redis 中存储至少 400 个这样的用户的数据,并且能够以 10/20 的块为分页检索特定用户的数据。我还需要能够按任何字段集(字符串)、int1、int2 ...(我有大约 22 个 int 字段)进行排序,还需要按任何整数字段进行过滤(类似于 sql WHERE 子句 9000

  1. redis 也可以做出类似于 SQL WHERE set LIKE '%value%' 的东西吗?

【问题讨论】:

  • 没办法回答。如果您将内容存储在 ram 中,那么您将占用 ram 来保存该数据,这意味着用于其他所有内容的 ram 更少。
  • 我的另一个问题是索引。表是如何编入索引的,您的查询是否利用了索引。
  • 您不会像在(例如)mysql 数据库中那样将数据存储在 redis 中。 redis 是一个优秀的键值存储,而不是 mysql
  • @Marc B,服务器是专用的。只有我在使用它,所以我几乎可以使用所有 24Gb 的内存
  • @Jay Blanchard,1 varchar(6) 字段上有索引 - 会话 id 和 1 个整数 - 另一个 id。两个字段的值必须不同,最多不超过过去一小时内的用户数

标签: php mysql sorting redis phpredis


【解决方案1】:

如果您可以将所有数据保存在内存中,Redis 可能非常适合您的问题。但是你必须重新考虑你的数据结构。 Redis 与关系型数据库有很大的不同,没有直接迁移。

至于你的问题。

  1. 可能有助于提高性能。多少,取决于您的用例和数据结构。您的约束将不再是硬盘,而可能是其他东西。

  2. Redis 没有类似于 ORDER BY 或 WHERE 作为 SQL 的概念。您将负责维护您的索引和过滤器。

我会为每个“记录”创建一个 HSET,然后使用几个 ZSET 来创建该记录的索引。 (如果您真的需要在任何字段上订购,那么您将需要每个字段一个 ZSET)

对于过滤器,用于索引的 ZSET 可能对过滤 int 值范围很有用。

很遗憾,对于 LIKE 查询,我真的没有答案。当我需要高级搜索功能时,我通常使用 ElasticSearch(结合 redis 和/或 mysql)

【讨论】:

    【解决方案2】:

    1。用 Redis 代替 MySQL 能提高性能,能提高多少?

    是的,Redis 可以提高您的基本读/写性能,因为它将信息直接存储在内存中。 This post 描述了性能提高了 3 倍,但该帖子的日期是 2009 年,因此从那以后数字可能已经改变。

    但是,只有您有足够的内存,这种性能提升才有意义。一旦超过分配的内存量,您的服务器将开始交换到磁盘,从而大大降低 Redis 性能。

    另外要记住的是,存储在 Redis 中的信息在默认情况下并不保证是持久的——the data set is only stored every 60 seconds or if at least 1000 keys change。其他更改将在服务器重新启动或断电时丢失。

    2。如何将生成的数据存储在 redis 中,以便我可以为 1 个用户检索它并按任何值对其进行排序并过滤它?

    Redis 数据存储方式与传统关系型数据库不同。它不提供复杂的排序,但可以通过sorted setsSORT command 完成基本排序。这必须由 PHP 服务器完成。

    Redis 确实有任何搜索支持——它必须由您的 PHP 服务器实现。

    3。结论

    在我看来,处理您所要求的最佳方式是使用 Redis 服务器进行缓存 和 MySQL 服务器来存储您需要持久的信息(如果您不有任何必须持久的信息,你可以只拥有 Redis 服务器)。

    你说过

    数据需要在有限的时间内保存 - 每隔一小时 整个表都被删除并重新创建。

    这对于 Redis 来说是完美的。 Redis 支持通过EXPIRE 对键执行TTL 命令,它会在设定的时间后自动删除一个键。这样您就不需要删除并重新创建任何表——Redis 会为您完成。

    【讨论】:

    • 好的,那么我如何在redis中表示这个数组并获取按int1排序的数据? $user_data = 数组(数组(“id”=>1,“session”=“3124”,“set”=>“set1”,“int1”=>1,“int2”=>11,“int3”=> 111, "int4"=>1111), 数组("id"=>2, "session"="1287", "set"=>"set2", "int1"=>2, "int2"=>22, "int3"=>222, "int4"=>2222))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 2015-10-07
    • 1970-01-01
    • 2018-08-23
    • 2021-08-22
    • 2016-08-22
    相关资源
    最近更新 更多