PgSQL · 应用案例 · 海量用户实时定位和圈人-团圆社会公益系统

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介:

背景

老人、儿童是最容易走丢的人群,一定要看好老人和小孩,但是万一走丢了怎么办呢?

阿里有一个公益系统,团圆,这个系统是用来帮助发布走丢人群信息的,公安通过发布的走丢人的照片,最后一次的位置信息,向社会发布。

通过公益平台的合作伙伴(例如运营商、购物软件等)可以向最后一次走丢人士出现的位置附近的人推送寻人启事,调动社会力量帮助寻找丢失人。

为了实现这个目的,需要收集社会人士的实时位置,现在有很多技术可以实现,例如手机基站定位、GPS定位等。

假设有10亿手机用户,用户的位置实时变动,实时的位置信息需要更新到数据库中。每天可能有千亿次位置更新。

同时发布走失信息后,需要到数据库中,根据走失位置圈出附近的人。

简单粗暴设计

1、表结构设计:

create table tbl_pos( 
 id int primary key, -- 用户ID 
 pos point -- 用户实时位置 
); 

2、空间索引

create index idx_tbl_pos on tbl_pos using gist(pos); 

性能评测

实时更新10亿用户位置,使用insert on conflict语法。

vi test.sql 
 
\set id random(1,1000000000) 
insert into tbl_pos values (:id, point(random()*180,random()*90)) on conflict (id) do update set pos=excluded.pos; 

使用32个并发,实时生成用户随机位置.

nohup pgbench -M prepared -n -r -P 5 -f ./test.sql -c 32 -j 32 -T 120000 > ./pos.log 2>&1 & 

1、实时位置更新TPS,约18万/s。

179799 

服务器负载,服务器还是非常空闲的,有足够的资源提供给查询

top - 01:52:34 up 76 days, 15:32, 2 users, load average: 33.74, 33.56, 31.47 
Tasks: 1064 total, 34 running, 1030 sleeping, 0 stopped, 0 zombie 
%Cpu(s): 47.6 us, 5.4 sy, 0.0 ni, 46.9 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st 
KiB Mem : 52807456+total, 32911484+free, 10949652 used, 18801006+buff/cache 
KiB Swap: 0 total, 0 free, 0 used. 42997945+avail Mem 

2、查询性能。

在位置更新的同时,测试查询性能。

假设走失人口最后位置出现在杭州,那么我们需要查询在某个平面(例如杭州市)内的点。返回500万个点(社会用户),仅需28秒。

使用空间索引,返回速度杠杠的。

postgres=# explain (analyze,verbose,timing,costs,buffers) select * from tbl_pos where box(point(1,1), point(25.5,25.5)) @> pos limit 5000000; 
 QUERY PLAN 
------------------------------------------------------------------------------------------------------------------------------------------------------- 
 Limit (cost=0.55..412954.11 rows=407872 width=20) (actual time=1.433..27536.623 rows=5000000 loops=1) 
 Output: id, pos 
 Buffers: shared hit=6183117 dirtied=31842 
 -> Index Scan using idx_tbl_pos on public.tbl_pos (cost=0.55..412954.11 rows=407872 width=20) (actual time=1.431..26861.352 rows=5000000 loops=1) 
 Output: id, pos 
 Index Cond: ('(25.5,25.5),(1,1)'::box @> tbl_pos.pos) 
 Buffers: shared hit=6183117 dirtied=31842 
 Planning time: 0.353 ms 
 Execution time: 27950.171 ms 
(9 rows) 

实际查询用,可以使用游标,流式返回。例子

通过游标,客户端可以边接收,边发短信或者向软件推送寻人启事。

实现流式推送,节省宝贵的寻人时间。

优化设计

单表十亿空间数据,对于查询来说,前面已经看到了,毫无压力。但是随着频繁的更新,可能到GiST索引的膨胀,膨胀后,PostgreSQL提供了并行创建索引的方法(不影响堵塞,可以在一个列创建同样的索引),来维护索引。但是10亿数据创建索引会变得很久。

为了解决这个问题,建议使用分区表。例如将ID哈希,分成64个分区,每个分区1500万左右数据。

在PostgreSQL中,目前性能最好的分区是pg_pathman插件。或者使用schemaless的方式。下面以schemaless为例子。其实在我曾经写过的另外的案例中也非常常见

《行为、审计日志 (实时索引/实时搜索)建模 - 最佳实践 2》

《PostgreSQL 时序最佳实践 - 证券交易系统数据库设计 - 阿里云RDS PostgreSQL最佳实践》

定义基表

postgres=# create table tbl_pos(id int primary key, pos point); CREATE TABLE 
postgres=# create index idx_tbl_pos_1 on tbl_pos using gist(pos); CREATE INDEX 
定义自动建表函数
create or replace function create_schemaless( 
 target name, -- 目标表名 
 src name -- 源表名 
) returns void as $$ 
declare begin execute format('create table if not exists %I (like %I including all)', target, src); execute format('alter table %I inherit %I', target, src); 
exception when others then 
 return; 
end; 
$$ language plpgsql strict; 
定义以schemaless的方式写数据的函数

创建一个插入数据的函数,使用动态SQL,如果遇到表不存在的错误,则调用建表函数进行建表。

create or replace function ins_schemaless( 
 id int, -- id 
 md int, -- 取模数 
 pos point -- 位置 
) returns void as $$ 
declare 
 target name := 'tbl_pos_'||mod(id,md) ; begin execute format('insert into %I values (%L, %L) on conflict (id) do update set pos=point_add(%I.pos, point(random()*10-5, random()*10-5))', target, id, pos, target); -- 为了模拟真实情况,因为人的移动速度有限,即使驾车,飞机(少数情况),所以用了pos=point_add(%I.pos, point(random()*10-5, random()*10-5))这种方法模拟更真实的情况  -- 实际场景,请改成pos=excluded.pos 
 exception 
 WHEN SQLSTATE '42P01' THEN 
 perform create_schemaless(target, 'tbl_pos'); 
 execute format('insert into %I values (%L, %L) on conflict (id) do update set pos=point_add(%I.pos, point(random()*10-5, random()*10-5))', target, id, pos, target); -- 为了模拟真实情况,因为人的移动速度有限,即使驾车,飞机(少数情况),所以用了pos=point_add(%I.pos, point(random()*10-5, random()*10-5))这种方法模拟更真实的情况  -- 实际场景,请改成pos=excluded.pos  end; 
$$ language plpgsql strict; 

数据库端的schemaless会牺牲一部分性能,因为无法使用绑定变量。

如果可能的话,建议业务层实现schemaless(自动拼接表名,自动建表,自动写入),以提高性能。

测试功能

postgres=# select ins_schemaless(2,32,point(1,2)); 
 ins_schemaless 
---------------- 
 
(1 row) 
 
postgres=# select ins_schemaless(1,32,point(1,2)); 
 ins_schemaless 
---------------- 
 
(1 row) 
 
postgres=# select tableoid::regclass,* from tbl_pos; 
 tableoid | id | pos 
-----------+----+------- 
 tbl_pos_2 | 2 | (1,2) 
 tbl_pos_1 | 1 | (1,2) 
(2 rows) 

schemaless设计压测

vi ~/test.sql 
\set id random(1,1000000000) 
select ins_schemaless(:id, 32, point(random()*360-180, random()*180-90)); 
 
 
nohup pgbench -M prepared -n -r -P 5 -f ./test.sql -c 32 -j 32 -T 120000 > ./pos.log 2>&1 & 

性能依旧杠杠的。

125977 tps 
小结

1、通过PostgreSQL的空间数据类型、空间索引。加上insert on conflict的特性。实现了单机约18万行/s的10亿用户的实时位置更新,同时输出500万个点的量级,仅需20几秒。真正实现了团圆公益系统的时效性。
2、采用游标,流式返回,实现了边获取数据,边向社会各界发送寻人启事的目的。
3、另一方面,用户位置的变更,实际上是有一定过滤性的,比如用户从办公室去上个洗手间,虽然位置可能发生了变化,但是非常细微,这种变化在这套系统中可以过滤(不更新),从而减少数据的更新量。
按照现有的测试数据,可以做到每天155亿次的更新。假设每10条更新仅有1条是有效更新,那么实际上可以支持1550亿次的MOVE采集。
4、PostgreSQL是一个很有爱心的数据库系统哦。
5、将来流计算引擎pipelinedb插件化后,PostgreSQL内部将整合这个流计算引擎,通过流计算引擎,理论上可以轻松实现40万行/s级别的更新速度,每天支撑300多亿次的实时位置更新。
6、采用流计算的方法除了提高性能,同时也降低了XID的消耗,在目前32BIT XID的情形下,可以有效的环节FREEZE带来的负担。如果不使用流计算,也建议合并更新,例如一个事务中更新若干条,比如100条,那么一天的事务数就将到了1.5亿。
7、参考

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
5月前
|
安全 算法 大数据
报名进行中|阿里数纳斯·2024企业内外数据流通交流会——数纳斯跨域商业增长引擎全新发布
随着大数据时代的到来,企业内部以及企业之间的数据流通已成为企业运营和发展的重要支撑。然而,对于集团型企业而言,数据内外流通面临着独特的挑战和困难。为解决这些问题,阿里巴巴数据技术及产品部将于2024年1月10日举办数纳斯 | 2024企业内外数据流通交流会,聚焦集团型企业数据流通难题,共话数据流通解决方案。
|
8月前
|
运维 算法 开发者
数据洞察创新挑战赛复赛启动,多重好礼送不停
9月8日,数据洞察创新大赛复赛正式拉开了帷幕,为了给选手更好的参赛体验 ,复赛专项训练营、大赛专题征文活动、限时冲榜活动也随之展开。
656 4
|
缓存 人工智能 自然语言处理
用户平台前端团队·双周技术见闻 2023-03-15
本期关键词:GPT-4、RSPack、Copilot CLI、TypeScript 5.0 rc。GPT-4AI 再进化,“他”越来越聪明了。在 3.15 凌晨,OpenAI 发布了生成式预训练模型的第四代:GPT-4,它带来了「多模态」、「逻辑能力显著提升」以及「输入输出上限提高」这三个非常重要的能力:多模态,现在你可以为模型输入图片了,GPT-4 能理解梗图并分析笑点,同时使用人类的逻辑来检查
|
存储 人工智能 运维
媒体观点|预判“四化”,阿里云把脉数据库最新发展方向
11月3日,在2022云栖大会上,阿里云全面提出数据库向云原生一站式数据管理与服务纵深发展战略
媒体观点|预判“四化”,阿里云把脉数据库最新发展方向
|
数据库 关系型数据库 分布式数据库
今日开启! 论道数据价值,阿里云数据库精英与你相约2019数据技术嘉年华
这是一个数据的时代,在互联网技术的推动下,数据在开放融合中正在创造前所未有的价值;创新的数据技术也在不断激发企业业务模式的革新,以数据聚集、数据挖掘、数据运营为驱动的数据企业正在加速成长。有效地组织数据,并利用数据创造价值,已经成为企业竞争的新的制高点。
549 0
|
安全 数据安全/隐私保护
浙江省政府联合阿里发布政务钉钉 改变公务员传统工作方式
2019年10月21日,乌镇第六届世界互联网大会现场,浙江省政府与阿里巴巴集团合作开发的政务钉钉首次正式发布。
599 0
|
新零售 搜索推荐 SEO
某知名电商网站营销总监教你如何做[伪原创]内容,搞网络推广的必看!!!
这是一篇关于伪原创写作的帖子,写这个并不是鼓励大家去抄改编,只是教大家如何利用别人的资源,以掘取到更多的资源。在网络中,最重要的部分无疑是内容,网站只是一种内容的体现。内容为王总是对的。但这不是说你能写出原创的内容,就能在网络上称王称霸了。
1200 0
「镁客·请讲」健康有益李宇欣:做垂直健康领域的第一个技术开放平台
它们围绕AI技术,做健康管理产业上游入口的平台技术授权,同时也承担着下游技术应用的落地。
408 0
|
自然语言处理 算法 测试技术
阿里巴巴高杰:3年风雨路,阿里巴巴自然语音交互的探索与经验教训
随着语音交互、自然语言处理、多模态等技术的发展,人机交互方式已经变得越来越简单,目前人机交互已经成为行业最热的研究方向之一。那么,未来人机交互的发展趋势什么呢?阿里巴巴智能语音交互专家高杰在《云栖大讲堂第三期|未来人机交互技术沙龙》上为大家分享了在阿里巴巴智能个人助理构建过程中所积累的经验和教训。
7586 0