目录
1. 实际问题
实际业务中,会有非常大的地理数据集的存储需求,比如全世界的点状POI,数据量级已达亿级别,存储在单一的PostgreSQL数据表中,若查询涉及到全表扫描,性能会差很多,如果对这些数据进行空间分析,复杂的计算,动不动就耗时十几二十分钟,不能满足实时的要求,因此,我们开始寻找一个可以解决这个问题的方案。
要找方案,我们首先要弄清楚原来的瓶颈在哪里。为什么存储在单表中性能差?
- 记录量太大,扫描记录时间过长;
- 写入和更新时会产生表级的锁,其他的写入和更新操作只能等待;
- 单磁盘I/O性能有限,若数据分布式存储在不同的磁盘,则I/O上限增加。
可能的解决方案
水平分表,是比较传统的处理数据量较大的单表的方法,可以有效的减小索引的大小,但分表一般存储在同一个数据库服务器,仍然受制于单磁盘I/O。因此,较好的方案是将分表分布到不同的数据库服务器,这就给了我们使用多个数据库并行处理的可能,还可以对单个分表做副本,冗余存放实现高可用。
但这两种方法都有一些问题,而这些问题我们自己来处理就太麻烦了:
- 需要更复杂的SQL,需要在SQL中加入shard或分表的逻辑;
- 维护分表的分布逻辑;
- 数据的导入和备份困难;
- 单点的故障可能导致整个集群不可用。
有没有现成的方案,先借鉴借鉴。
2. Citus是什么
首先,`Citus`是一个PostgreSQL的扩展,类似于PostGIS、pgRouting,它主要的作用是将一张大表进行水平分表,每个分表称为“分片(Shard)”,按照一定的规则分布(?)到多台机器上,并且将查询分布到不同节点并行执行,最后汇总结果。
Citus是单coordinator,多worker结构,coordinator统筹协调,worker节点是真正存储数据和执行查询的地方。如下图 ?
从Citus官网盗了一张图来,这张图说的很清楚,当存储数据时,Coordinator节点会把当前表分为多个分片(shard),并将分片安装某种算法分布到各个