我计划归档邮件,但不确定应该使用哪个。
它应该能够容纳最多 200 亿行(这就是我期望的总数)
每行将包含三列:user_id、消息、日期
user_id 是一个 30 个字符的字符串。该消息的长度介于 1 - 20 000 个字符之间。我预计平均为 140 个字符。(UTF-8,它应该允许表情符号、不同的字母表等)
我只想要 user_id 的索引,而不是消息/日期的索引。
我只计划进行 INSERT 查询,并且非常简单 SELECT * WHERE user_id = XXXXX 会有很少的 SELECT,我预计峰值为 10 个/分钟。SELECT 不需要太快,1 到 20 秒之间的任何时间都可以。
但是会有很多INSERT。大概每秒5000-10000次。
我的服务器将配备: CPU:AMD Ryzen™ 9 7950X3D RAM:128 GB DDR5 ECC 驱动器:1x 7.68 TB NVMe SSD 数据中心(来自 Hetzner)
我们来算一下每条消息有 180 字节(包括 user_id、时间戳和开销),其中 20B 条消息相当于 3.6 Tb,已经是相当大的数据块了。
为了避免随机 IO,我更喜欢可以将具有相同索引键(在本例中为 user_id)的行在存储中紧密聚集在一起的数据库。这将加快您的 SELECT 速度,如果您按 (user_id,timestamp) 排序,而数据已按该顺序存储,则不需要排序。
Postgresql 需要一个额外的索引来重复数据。
MySQL/MariaDB 上的 InnoDB 自动根据主键进行集群,因此如果将 (user_id,timestamp) 定义为 PK,则满足该条件。InnoDB 还支持使用 lz4 等现代算法进行页面压缩。如果可能,在插入一批行时,应按主键对它们进行排序。MySQL大家都知道,我就不多说了。
另一个选择是Clickhouse。虽然它使用 SQL,但它并不完全像通常的关系数据库。例如,它不执行更新或外键。它适用于 OLAP/数据仓库,这正是您正在做的事情。它确实满足这两个条件:使用MergeTree引擎,数据会自动按照您指定的顺序存储,因此它将被聚类,并且它支持压缩。它有点挑剔并且难以配置。如果你将它用于它应该做的事情,那么性能通常是荒谬的。让我们尝试一个非常愚蠢的查询:
至于 INSERT,您应该每秒执行大约 1-10 次批量操作。此外,当您只能对所有行进行分组时,每秒执行数千个 INSERT 语句绝不是一个好主意。python 接口支持数组的批量插入。例子:
压缩统计:
在这个简单的例子中,我们每秒插入 260 万行,对于这个公认易于压缩的文本,压缩比约为 5。Python 最多使用一个核心 37.5 秒发送数据,而数据库使用了 21 秒的 CPU 时间。基本上,它没有做太多事情,其余的核心都在闲置。
任何。
大多数现代数据库系统没有行数的数据限制。静态数据的大小不会影响性能。
您有一个非常简单且已定义的架构。您还有非常简单的用例。因此,任何现代 RDBMS 都可能是一个不错的选择。如果您想要一个具有大量用户支持和功能且免费的产品,那么 PostgreSQL 是一个不错的选择。如果可以使用付费的企业级软件,SQL Server 也是一个很好的选择。其他不错的选择包括 MariaDB、Oracle SQL 和 MySQL。
Message
FWIW,我过去曾在 RDBMS (SQL Server) 中存储大量数据(特别是电子邮件消息)。主表有数十亿行那么大,在高峰时段我们每秒插入数千行。从该表中查询少量数据也很快(不到一秒)。服务器背后的硬件配置也比您计划使用的要少得多。