6

我有一个 mysql 数据库,每天约有 1.5 亿次插入,保留期约为 60 天。

  1. 每条记录都以 id 为索引。
  2. 每次更新发生如下:
    1. 查看记录是否存在。如果是,则使用新数据进行更新。
    2. 否则创建数据。
  3. 删除 60 天前创建的记录。

我的主要用例如下:

运行一些批量查询。例如。:

Select (*) from table where prop=val1 and prop2=val2 etc

将返回大量记录,例如。1M

以下方法是否良好:

  1. 拥有一个仅在 id 上具有索引的主数据库。保留 60 天。
  2. 已读取副本数据库。该数据库将在许多列上建立索引
  3. 所有批量查询都将针对只读副本数据库运行。

这是一个好的解决方案吗?

编辑:我计划使用 Amazon RDS DB 并在他们的文档中找到了这个:

 Q: Can my Read Replicas only accept database read operations?

只读副本旨在为读取流量提供服务。但是,可能存在高级用户希望针对只读副本完成数据定义语言 (DDL) SQL 语句的用例。示例可能包括向用于业务报告的只读副本添加数据库索引,而不向相应的源数据库实例添加相同的索引。如果您希望为给定的只读副本启用读取以外的操作,则需要修改只读副本的活动数据库参数组,将“read_only”参数设置为“0”。</p>

4

5 回答 5

5

要回答您的问题:

以下方法是否良好:

  1. 拥有一个仅在 id 上具有索引的主数据库。保留 60 天。
  2. 已读取副本数据库。该数据库将在许多列上建立索引
  3. 所有批量查询都将针对只读副本数据库运行。

这是一个好的解决方案吗?

更新

以我的观点和经验,不。

从技术上讲,此解决方案可能有效,但实际上不适合生产使用。mysql内置master-slave replication的,只有从库中的表和主库中的表布局相同的情况下才有效。

您将拥有大约 90 亿条记录 (150 x 60)。我的估计是在磁盘上这可能需要 1TB(每条记录相当于一条推文的大小)。1.5 亿次插入和 1.5 亿次删除(过期记录)肯定会使索引碎片化且inserts速度变慢,需要频繁地重新构建。

当您需要多个只读副本时,事情会变得越来越复杂,这是生态系统的自然演变。

如果您每天有 1.5 亿次插入,则应该考虑使用NOSQL数据库。Mongodb以前也支持Innodb,不知道现在还支持。

如果您希望坚持使用 RDBMS 之类的MySQL,您应该使用诸如Database Sharding之类的策略。在此策略中,您以这样一种方式对数据进行分段,即负载分布在 MySQL 实例集群中。

与分片相比,可扩展性稍差的是使用MyISAM等存储引擎。MyISAM 不完全符合 ACID,但提供了出色的性能。它支持并发插入。

于 2013-10-14T16:52:26.557 回答
1

如果您的主要用途是 SELECT *,在不同的列上没有连接和多个过滤器,请考虑使用 Fastbit。Fastbit 实现了可以非常有效地评估的 WAH 压缩位图,并将数据存储为列存储。

https://sdm.lbl.gov/fastbit/

对于 MySQL,也许考虑支持“聚集”索引的 TokuDB,或者在 InnoDB 中创建覆盖索引。仅当您要过滤的属性组合很小时,这才真正有效。如果没有,请考虑 fastbit。

如果您总是过滤相同的属性,那么您可以考虑使用 Flexviews: http ://flexvie.ws

您可以为 select * from table where val1=X and val2=Y 创建一个视图

或者只是推出你自己的版本。加载数据后做:替换为summary_table_v2v2 select * from table where val1=X and val2=Y and table.last_update > NOW()-INTERVAL 1 DAY;

假设 last_update 是时间戳列,这将使用最后一天所做的任何更改“刷新”表。

于 2013-10-12T06:05:52.920 回答
1

@eternal-learner 的答案不正确。

是的,您概述的方法可能是一个好方法。您需要采取一些预防措施:

  1. 在进行索引更改之前确保主从复制正在工作

  2. 仅在从站中进行所有索引更改,并确保仅进行不能破坏数据模型逻辑的索引更改(即不要引入新的唯一索引/约束)

  3. 确保在故障转移情况下不能将从属设备提升为主控设备,否则您最终会得到一个性能较低的主控设备,其索引与组中任何其他从属设备不同

另外——要小心你如何进行更新或插入。那里很容易出现竞争条件。

于 2013-10-17T14:33:13.220 回答
0

聚集索引

无论您使用复制数据库但您的设计数据库不是面向更大的表,您的性能都不会发生任何变化。

我建议您在阅读以下链接后查看您的设计:

InnoDb 索引类型

在这里,您可以找到一些关于仅使用 innodb 表的聚集索引的示例。

6000万条条目,选择某月的条目。如何优化数据库?

它适用于 60 到 5 亿行。

搜索引擎

在另一种选择中,您可以使用像 Sphinx 这样的搜索引擎是开源的,但是您的数据库设计应该处于非规范化模式,在这种模式下,您可以将多列转换为一列,例如:

Select (*) from table where prop=val1 and prop2=val2 and prop3=val3 ..

像这样创建一个唯一的列索引: val_tot = concat(val1, val2, val3,..)

Select (*) from table where prop_key = val_tot;
于 2013-10-11T04:52:49.840 回答
0

我还没有尝试过,但我认为复制不支持主从之间的不同表结构。我没有找到任何来自 Mysql 的文档。这个想法是 mysql 会不时地从 master 到 slaver 重放二进制日志,因此所有结构应该相同以避免冲突。

要处理庞大的数据库问题,另一种选择是mysql 分区,或者您可以使用脚本将大量数据重新计算为具有良好索引的小数据。

于 2013-10-12T17:08:34.417 回答