|
| 1 | +## (新零售)商户网格化运营 - 阿里云RDS PostgreSQL最佳实践 |
| 2 | + |
| 3 | +### 作者 |
| 4 | +digoal |
| 5 | + |
| 6 | +### 日期 |
| 7 | +2017-08-02 |
| 8 | + |
| 9 | +### 标签 |
| 10 | +PostgreSQL , PostGIS , 地理位置 , KNN , 近邻检索 , 网格检索 , polygon中心点 , 半径搜索 |
| 11 | + |
| 12 | +---- |
| 13 | + |
| 14 | +## 背景 |
| 15 | +伟大的马老师说: |
| 16 | + |
| 17 | +“纯电商时代很快会结束,未来的十年、二十年,没有电子商务这一说,只有新零售这一说,也就是说线上线下和物流必须结合在一起,才能诞生真正的新零售” |
| 18 | + |
| 19 | +线上是指云平台,线下是指销售门店或生产商,新物流消灭库存,减少囤货量。 |
| 20 | + |
| 21 | +电子商务平台消失是指,现有的电商平台分散,每个人都有自己的电商平台,不再入驻天猫、京东、亚马逊大型电子商务平台。举例:每个人在电商平台都有自己的店铺,集中在平台下进行销售,只能在一块水池里生活,这是很局限性的。 |
| 22 | + |
| 23 | +要打通线上线下、消灭库存,需要发挥数据的价值,比如通过数据预测销量。同时线上线下对接,也对数据运营产生了新的挑战,比如基于地理位置的网格化运营由来而生。 |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +## 一、需求 |
| 28 | +1、支持基于地理位置(GIS)的快速数据检索。 |
| 29 | + |
| 30 | +2、支持海量销售数据的分析、挖掘。 |
| 31 | + |
| 32 | +## 二、架构设计 |
| 33 | + |
| 34 | + |
| 35 | +1、海量的销量数据通过OSS并行进入到阿里云HybridDB for PostgreSQL数据库。 |
| 36 | + |
| 37 | +2、RDS PostgreSQL负责在线事务处理,网格化运营的任意多边形圈选商户。 |
| 38 | + |
| 39 | +3、ETL程序,负责数据调度。 |
| 40 | + |
| 41 | +4、BI应用对接HDB for PG和PG,驱动和语法与PostgreSQL兼容。 |
| 42 | + |
| 43 | +5、HybridDB for PostgreSQL提供高可用、备份的基本功能,同时提供了一键扩容的功能。用户不需要担心未来数据增长的性能压力。 |
| 44 | + |
| 45 | +6、HDB PG和RDS PG可以通过OSS_EXT外部表插件,透明访问(读写)OSS的数据。OSS提供海量共享存储,RDS PG和HDB PG之间通过OSS可共享数据,同时OSS还可以作为外部海量数据来源并行导入到HDB PG的高速通道。OSS还可以作为RDS PG和HDB PG的冷数据存储。 |
| 46 | + |
| 47 | +## 三、DEMO与性能 |
| 48 | +### 1 商户网格搜索 |
| 49 | +1、构造1亿商户地理位置数据 |
| 50 | + |
| 51 | +``` |
| 52 | +postgres=# create table pos(id int, pos point); |
| 53 | +CREATE TABLE |
| 54 | +postgres=# insert into pos select generate_series(1,100000000), point(5000-random()*10000, 5000-random()*10000); |
| 55 | +INSERT 0 10000000 |
| 56 | +postgres=# select * from pos limit 10; |
| 57 | + id | pos |
| 58 | +----+--------------------------------------- |
| 59 | + 1 | (603.396683000028,3740.25050085038) |
| 60 | + 2 | (4177.6926163584,4295.85348349065) |
| 61 | + 3 | (-2897.50102907419,4393.90230923891) |
| 62 | + 4 | (-2756.50105439126,2930.08491862565) |
| 63 | + 5 | (-1679.21951506287,-2329.10942286253) |
| 64 | + 6 | (2323.99420812726,-4727.32939757407) |
| 65 | + 7 | (-1572.33712729067,-3614.81220461428) |
| 66 | + 8 | (-1383.57343617827,312.93470878154) |
| 67 | + 9 | (-2942.08695180714,4876.54477357864) |
| 68 | + 10 | (-2387.8013016656,-141.320424154401) |
| 69 | +(10 rows) |
| 70 | +``` |
| 71 | + |
| 72 | +2、创建空间索引 |
| 73 | + |
| 74 | +``` |
| 75 | +postgres=# create index idx_pos on pos using gist(pos); |
| 76 | +``` |
| 77 | + |
| 78 | +3、创建查询优化函数 |
| 79 | + |
| 80 | +输入任意多边形,返回落在多边形中的商户。 |
| 81 | + |
| 82 | +``` |
| 83 | +select * from pos where polygon('((10,2),(-10,-100),(0,10))') @> pos; |
| 84 | +``` |
| 85 | + |
| 86 | +如果需要带其他条件的空间查询,可以使用空间复合分区索引(PARTIAL INDEX),例如 |
| 87 | + |
| 88 | +``` |
| 89 | +create index idx_pos on pos using gist(pos) where 分区条件1; |
| 90 | +... |
| 91 | +create index idx_pos on pos using gist(pos) where 分区条件n; |
| 92 | +``` |
| 93 | + |
| 94 | +详见 |
| 95 | + |
| 96 | +[《分区索引的应用和实践 - 阿里云RDS PostgreSQL最佳实践》](../201707/20170721_01.md) |
| 97 | + |
| 98 | +4、空间索引性能验证,一亿数据网格查询约 0.8 毫秒。 |
| 99 | + |
| 100 | +``` |
| 101 | +postgres=# explain (analyze,verbose,timing,costs,buffers) |
| 102 | + |
| 103 | +select * from pos where polygon('((10,2),(-10,-100),(0,10))') @> pos; |
| 104 | + |
| 105 | + QUERY PLAN |
| 106 | +----------------------------------------------------------------------------------------------------------------------------------- |
| 107 | + Index Scan using idx_pos on postgres.pos (cost=0.42..123470.72 rows=100000 width=20) (actual time=0.099..0.737 rows=618 loops=1) |
| 108 | + Output: id, pos |
| 109 | + Index Cond: ('((10,2),(-10,-100),(0,10))'::polygon @> pos.pos) |
| 110 | + Buffers: shared hit=660 |
| 111 | + Planning time: 0.031 ms |
| 112 | + Execution time: 0.778 ms |
| 113 | +(6 rows) |
| 114 | + |
| 115 | +postgres=# select * from pos where polygon('((10,2),(-10,-100),(0,10))') @> pos; |
| 116 | + id | pos |
| 117 | +----------+------------------------------------------ |
| 118 | + 14028137 | (-9.47874505072832,-94.8515953496099) |
| 119 | + 43891480 | (-9.1992225497961,-92.9797394201159) |
| 120 | + 1247175 | (-0.888188369572163,-28.0744722113013) |
| 121 | + 4631961 | (-0.548232346773148,-31.1226723715663) |
| 122 | + 5458615 | (-1.67813152074814,-29.4832326471806) |
| 123 | + 6057261 | (-0.965241342782974,-24.8730508610606) |
| 124 | + ...... |
| 125 | + 72818882 | (-0.214213505387306,-38.5544309392571) |
| 126 | + 84374336 | (-0.350810587406158,-38.3379962295294) |
| 127 | + 93014418 | (1.69238075613976,-38.5063700377941) |
| 128 | + 94375565 | (-0.0325776636600494,-43.1329058483243) |
| 129 | +(618 rows) |
| 130 | +``` |
| 131 | + |
| 132 | +### 2 数据分析性能 |
| 133 | +数据分析能力如何呢? |
| 134 | + |
| 135 | +这里有一组单机1TB的TPC-H测试数据,HybridDB for PostgreSQL是MPP分布式数据库,可以通过增加节点线性提升性能。 |
| 136 | + |
| 137 | + |
| 138 | + |
| 139 | +另外还有一些测试数据可以参考如下: |
| 140 | + |
| 141 | +[《TPC-H测试 - PostgreSQL 10 vs Deepgreen(Greenplum)》](../201707/20170714_01.md) |
| 142 | + |
| 143 | +[《100TB级, 日增量1TB(100亿)的OLTP OLAP混合场景数据库设计方向》](../201707/20170703_01.md) |
| 144 | + |
| 145 | +## 四、技术点 |
| 146 | +1、空间索引,GiST索引是PostgreSQL独有的空间索引,支持精准的距离索引搜索,同时支持按举例远近排序返回结果。性能杠杠的,也是很多科研机构、空间业务的首选。 |
| 147 | + |
| 148 | +2、KNN查询,按距离由近到远输出记录。 |
| 149 | + |
| 150 | +3、OSS外部表,阿里云RDS PG和HDB PG增加的功能,与云端海量对象存储OSS打通,在数据库中以外部表的形式透明的读写OSS中的文件。可以达到每个线程约30MB/s的读写带宽,增加并发即可提高整体的吞吐。 |
| 151 | + |
| 152 | +4、ETL,云端或用户的ETL程序,只要支持OSS对象连接、PG的连接协议即可。 |
| 153 | + |
| 154 | +5、MADlib,是一个开源的机器学习库,支持大多数的学习库,通过RDS PG,HDB PG的SQL接口实现机器学习。 |
| 155 | + |
| 156 | +MADlib支持Classification, Regression, Clustering, Topic Modeling, Association Rule Mining, Descriptive Statistics, Validation等众多挖掘模型。 |
| 157 | + |
| 158 | + |
| 159 | + |
| 160 | +http://madlib.incubator.apache.org/product.html |
| 161 | + |
| 162 | +[madlib手册](http://madlib.incubator.apache.org/docs/latest/index.html) |
| 163 | + |
| 164 | +6、几何知识 |
| 165 | + |
| 166 | +多边形的内切圆,circle(polygon) |
| 167 | + |
| 168 | +多边形BOX和外圆,circle(box(polygon)) |
| 169 | + |
| 170 | +PG的几何函数如下 |
| 171 | + |
| 172 | +https://www.postgresql.org/docs/9.6/static/functions-geometry.html |
| 173 | + |
| 174 | +PostGIS的几何函数如下 |
| 175 | + |
| 176 | +http://postgis.net/docs/manual-2.3/reference.html |
| 177 | + |
| 178 | +7、以上性能测试涉及到的多边形搜索是PG 10的测试,如果你发现老版本存在空间索引的性能问题,可以用以下这个方法进行优化。 |
| 179 | + |
| 180 | +首先将多边形转换为BOX,再求BOX的外圆,通过KNN索引顺序返回记录,同时过滤多边形包含的数据。 |
| 181 | + |
| 182 | +``` |
| 183 | +create or replace function ff(polygon) returns setof record as $$ |
| 184 | +declare |
| 185 | + v_rec record; |
| 186 | + cir circle := circle(box($1)); -- 扩散边界 |
| 187 | + dist float8 := radius(circle(box($1))); -- 求多边形外圆的半径 |
| 188 | + centrid point := point(circle(box($1))); -- 求多边形外圆的中心点 |
| 189 | +begin |
| 190 | + set local enable_seqscan=off; -- 强制空间索引, KNN搜索 |
| 191 | + for v_rec in |
| 192 | + select * from pos order by pos <-> centrid |
| 193 | + loop |
| 194 | + if not cir @> v_rec.pos then |
| 195 | + return; |
| 196 | + elsif ($1 @> v_rec.pos) then |
| 197 | + return next v_rec; |
| 198 | + end if; |
| 199 | + end loop; |
| 200 | + return; |
| 201 | +end; |
| 202 | +$$ language plpgsql strict volatile; |
| 203 | +``` |
| 204 | + |
| 205 | +``` |
| 206 | +postgres=# select * from ff(polygon('((10,2),(-10,-100),(0,10))')) as t(id int, pos point); |
| 207 | + id | pos |
| 208 | +----------+------------------------------------------ |
| 209 | + 36646218 | (-0.0167591497302055,-45.0508715584874) |
| 210 | + 42498944 | (0.139414332807064,-44.4842409342527) |
| 211 | + 83455402 | (-0.350065529346466,-44.2021945491433) |
| 212 | + ...... |
| 213 | + 10828319 | (2.18123663216829,7.54482112824917) |
| 214 | + 70772435 | (2.13983003050089,8.06822907179594) |
| 215 | + 79346114 | (2.12917104363441,8.25083814561367) |
| 216 | +(618 rows) |
| 217 | +``` |
| 218 | + |
| 219 | +## 五、云端产品 |
| 220 | + |
| 221 | +[阿里云 RDS PostgreSQL](https://www.aliyun.com/product/rds/postgresql) |
| 222 | + |
| 223 | +[阿里云 HybridDB for PostgreSQL](https://www.aliyun.com/product/gpdb) |
| 224 | + |
| 225 | +[阿里云 OSS](https://www.aliyun.com/product/oss) |
| 226 | + |
| 227 | +## 六、类似场景、案例 |
| 228 | + |
| 229 | +[《(AR虚拟现实)红包 技术思考 - GIS与图像识别的完美结合》](../201701/20170113_01.md) |
| 230 | + |
| 231 | +[《从难缠的模糊查询聊开 - PostgreSQL独门绝招之一 GIN , GiST , SP-GiST , RUM 索引原理与技术背景》](../201612/20161231_01.md) |
| 232 | + |
| 233 | +[《时间、空间、对象多维属性 海量数据任意多维 高效检索 - 阿里云RDS PostgreSQL最佳实践》](../201707/20170722_01.md) |
| 234 | + |
| 235 | +[《空间复合索引加速空间搜索》](../201706/20170620_01.md) |
| 236 | + |
| 237 | +[《奔跑吧,大屏 - 时间+空间 实时四维数据透视》](../201704/20170413_02.md) |
| 238 | + |
| 239 | +[《视觉挖掘与PostGIS空间数据库的完美邂逅 - 广告营销\圈人》](../201703/20170328_04.md) |
| 240 | + |
| 241 | +[《PostgreSQL\GPDB 毫秒级海量时空数据透视 典型案例分享》](../201706/20170629_01.md) |
| 242 | + |
| 243 | +## 七、小结 |
| 244 | +新零售行业,通过打通线上线下、消灭库存,需要发挥数据的价值,比如通过数据预测销量。同时线上线下对接,也对数据运营产生了新的挑战,比如基于地理位置的网格化运营由来而生。 |
| 245 | + |
| 246 | +要求数据库具备: |
| 247 | + |
| 248 | +1、支持基于地理位置(GIS)的快速数据检索的能力。 |
| 249 | + |
| 250 | +2、支持海量销售数据的分析、挖掘的能力。 |
| 251 | + |
| 252 | + |
| 253 | + |
| 254 | +通过阿里云的RDS PostgreSQL、HybridDB for PostgreSQL、OSS,实现了亿级地理位置数据一毫秒内响应,同时支持分析、挖掘需求的全链路需求。 |
| 255 | + |
| 256 | +1、海量的销量数据通过OSS并行进入到阿里云HybridDB for PostgreSQL数据库。 |
| 257 | + |
| 258 | +2、RDS PostgreSQL负责在线事务处理,网格化运营的任意多边形圈选商户。 |
| 259 | + |
| 260 | +3、ETL程序,负责数据调度。 |
| 261 | + |
| 262 | +4、BI应用对接HDB for PG和PG,驱动和语法与PostgreSQL兼容。 |
| 263 | + |
| 264 | +5、HybridDB for PostgreSQL提供高可用、备份的基本功能,同时提供了一键扩容的功能。用户不需要担心未来数据增长的性能压力。 |
| 265 | + |
| 266 | +6、HDB PG和RDS PG可以通过OSS_EXT外部表插件,透明访问(读写)OSS的数据。OSS提供海量共享存储,RDS PG和HDB PG之间通过OSS可共享数据,同时OSS还可以作为外部海量数据来源并行导入到HDB PG的高速通道。OSS还可以作为RDS PG和HDB PG的冷数据存储。 |
| 267 | + |
| 268 | +## 参考 |
| 269 | +[《GIS附近查找性能优化 - PostGIS long lat geometry distance search tuning using gist knn function》](../201308/20130806_01.md) |
| 270 | + |
| 271 | +https://www.postgresql.org/docs/9.6/static/functions-geometry.html |
| 272 | + |
| 273 | +http://postgis.net/docs/manual-2.3/reference.html |
0 commit comments