自动分片postgresql?

Los*_*oul 20 database postgresql partitioning sharding

我有一个问题,我需要很快将数据(超过50亿行)加载到数据库中(理想情况下不到30分钟但更快更好),我最近建议调查postgresql(我用mysql失败了)并且正在看hbase/cassandra).我的设置是我有一个集群(目前有8个服务器)可以生成大量数据,我想在集群中的每台机器上本地运行数据库,它在本地快速写入,然后在最后(或整个数据生成)数据是合并在一起.数据不是任何顺序所以我不关心它在哪个特定服务器上(只要它最终存在).

我的问题是,是否有任何好的教程或地方可以了解PostgreSQL自动分片(我发现像sykpe这样的公司的结果做自动分片但没有教程,我想自己玩这个)?我正在尝试做什么?因为数据不是以任何顺序我将使用自动递增ID号,如果合并数据会导致冲突(这不再是一个大问题)?

更新:弗兰克的想法在某种程度上消除了我所询问的自动递增冲突问题.问题基本上是现在,我如何了解自动分片并支持分布式上传数据到多个服务器?

Cra*_*ger 14

第一:您是否真的需要将生成的数据从群集直接插入关系数据库?你不介意最后合并它,所以为什么还要插入数据库呢?在您的位置,我会让您的群集节点写入平面文件,可能是gzip的CSV数据.然后,我将使用像pg_bulkload这样的工具批量导入和合并该数据.

如果你确实需要直接插入关系数据库:这是(部分)PgPool-II和(特别是)PgBouncer的用途.配置PgBouncer以跨不同节点进行负载平衡,您应该进行相当多的排序.

请注意,PostgreSQL是一个具有强大数据持久性保证的事务数据库.这也意味着如果以简单的方式使用它,那么执行大量小写操作可能会很慢.您必须考虑您愿意在数据持久性,速度和硬件成本之间做出哪些权衡.

在一个极端,每个都INSERT可以是自己的事务,在返回成功之前同步提交到磁盘.这将每秒的事务数限制为您的磁盘子系统可以执行的fsync()数量,通常只有几十或几百秒(没有电池备份RAID控制器).如果你没有做任何特别的事情,如果你没有将你的INSERTs 包裹在BEGIN和中,这是默认的COMMIT.

在另一个极端,你说"我真的不在乎我是否丢失了所有这些数据",并使用未记录的表格来插入.这基本上为数据库提供了将数据丢弃的权限,如果它不能保证它是正常的 - 例如,在操作系统崩溃,数据库崩溃,断电等之后.

中间地带是你可能想要的地方.这涉及到的某种组合的异步提交,集团承诺(COMMIT_DELAYcommit_siblings),配料插入到包裹在明确的群体BEGINEND等代替INSERT配料你可以做COPY在时间的几千条记录负载.所有这些都会使数据的耐用性与速度相悖.

对于快速批量插入,您还应考虑插入表中,除了主键之外没有任何索引.也许甚至没有.批量插入完成后创建索引.这将是一个快得多的地狱.


Edm*_*und 2

以下是一些可能有帮助的事情:

  • 每个服务器上的数据库应该有一个小的元数据表,其中包含该服务器的独特特征。比如是哪个服务器;服务器可以按顺序编号。除了该表的内容之外,尝试使每个服务器上的架构尽可能相似可能是明智的。

  • 对于数十亿行,您将需要 bigint id(或 UUID 等)。使用 bigint,您可以为每个服务器分配大量范围,并设置其序列以使用它。例如,服务器 1 获取 1..1000000000000000,服务器 2 获取 1000000000000001 到 2000000000000000 等。

  • 如果数据是简单的数据点(例如每秒从 10 个仪器读取的温度读数),您可以通过将其存储在包含列的表中(time timestamp, values double precision[])而不是更正确的(time timestamp, instrument_id int, value double precision). 这是为了提高效率而进行的显式非规范化。(我在博客中讲述了我自己对这个计划的体验。)