基于 Elasticsearch 空间搜索的疫情追踪分析系统


00

背景

随着新冠肺炎在全球蔓延,政府在疫情防控方面投入了大量精力。然而常规地区的疫情监测是在固定的行政区域统计被感染人数,常规的个体疫情追踪则是个人主动上传信息辅助手机定位来评估健康指数。这样做不仅费时耗力,而且信息更新不及时会影响防控效果。


针对这些问题,我们小组开发了一套面向疫情防控密切接触人群大数据分析系统:使用测温手环高频采集人群体温等生物数据并实时上传,利用手机蓝牙探测周边设备蓝牙信号 RSSI 实时分析密切接触的关系网络,将地图划分为多个区块并采用 Geohash 进行编码并结合 SEIR 疫情传播模型进行区域安全指数的评估。


鉴于ES具有实时性,可扩展性以及可以把地理位置、全文搜索分析结合到一起的优点,我们使用ES兜底来存储区块信息、个人生物信息和关系网络。


01

使用 ES 存储区块信息

我们将整个地图沿经纬线进行近似矩形区块划分,利用Geohash函数给区块编码。为了实现在不同经度范围内的疫情监测,我们使用动态区块划分:若查看局部区块疫情则采用长二进制编码,划分区块数量更多,可以查看更细粒度的区域情况;若查看全局疫情则采用短二进制编码,划分区块数量少能从宏观上监测疫情变化。


划分后的任意区块包含该区块的用户集合,由于动态区块划分,随着用户位置的变动,后端会实时更新所有区块内的用户区块信息,如图所示我们可以通过左上的控件动态调整block块大小,实时显示各个block块的地区安全指数(ASI)。


Elasticsearch 提供了使用纬度-经度表示的座标点 `geo_point` 字段类型表示地理位置,我们使用 geo_point 标注用户地理位置信息。Elasticsearch 本身也支持 geohash 检索,我们可以很方便地根据区块名获得区块内的用户信息。


我们对每一个动态划分的矩形块给定一个唯一的 geohash 编码。划分数量、划分粗细粒度根据存放在Elasticsearch 中的用户危险等级和geo_point字段决定。


例如:当某一区块中的用户变少甚至没有时,将直接取消这一区块的划分(表面上表现为安全区块,实际已删除);当某个用户的危险等级变高时,我们将根据该用户在 Elasticsearch 中的历史 geo_point 字段值判断出用户去过的区块,为了更好地追踪轨迹,我们将尽可能细分这些危险的区块或及时下调区块的安全指数。


具体做法为:危险用户所在的安全大区块将被细分下去,我们的算法将计算出这些新划分出的小块的安全指数,这样就做到了对高风险地区区块的精细划分;另外,当大区块的安全状态恢复时,将使用更少的区块数对它进行动态划分。


通过这样的动态划分算法设计,我们在保证精准追踪危险区域的同时,也做到了一些算力的节省。如图:通过geo_point字段,我们在 Kibana 上追踪用户 uid 为2过去一周所经过的地区。


由于区块的信息是实时更新的,并且区块名就是 geohash 编码,因此我们很容易就能在地图上标记出区块信息。利用 Elasticsearch 中的检索功能可以轻松查出用户在过去一段时间内去过的地方,因此,用危险区块的 geohash 编码、用户的 geo_point 以及这些地理位置的历史时间,我们就能检索出有感染风险的用户。


综上,系统将根据 Elasticsearch 中用户的危险等级和 geo_point 来进行动态区块划分以及评分。

02

使用 ES 存储个人信息

为了实时检测用户的体温、心率等生物数据,提高算法模型评估用户健康安全指数的可靠性和准确性,我们采购了第三方手环并根据SDK开发App。实时发送用户体温,步数,心率等信息到后端并帮助用户分析周边疫情情况。因为查询对于延时要求高,所以我们还是使用ES存储。


如图所示为用户在自己的手机app内查看自己的生物数据以及手机蓝牙扫到附近的设备。


根据用户当日上传的体温数据及14日内行动轨迹通过定量计算用户安全指数的方法评定用户健康情况,安全指数范围0-60为危险,90-100显示健康,61-89程度介于两者之间。


如图所示用户可以在app中查看自己的健康安全指数和14天内的行迹。

03

使用 ES 存储关系网络

我们通过手机蓝牙会扫到近距离接触用户的RSSI强度和MAC地址并将接触时间,接触距离,接触频次等数据存入ES。


在此之前,我们曾对关系网络的存储方案做过探讨,使用neo4j来存储图关系并用Cypher查询目标接触人群可以满足需求,但是当数据库中的用户节点较多时,要快速查找满足条件的节点会比较耗时。另外,neo4j缺乏ES这样强大的全文检索能力。


考虑到用户的历史关系网络不会发生改变也不会频繁更新给后端数据库造成压力,我们最后决定使用ES来存储关系网络。我们使用ES提供的父子关系结构来存储中心用户手机蓝牙扫到的周边人群信息,这样做的好处是父子文档均被routing到同一分片,查询时效率较高。


疾控人员可以在前端输入用户id查询特定用户的关系网络,查询时我们采用懒加载模式:一级关系为直接接触人群,只需通过父文档查询子文档即可;二级关系为间接接触,也就是将一级关系查询到的子文档中的用户id再作为中心用户进行查询,以此类推。


为了防止在多级关系查询中双方互扫蓝牙设备造成有环的问题,我们将中心用户id与接触人群id按照大小排序并使用下划线连接用作全局唯一关键字。


另外,疾控中心需要查询的接触人群信息具有时效性,超出14天的接触人群基本不会考虑。基于此,我们增加了阻断权重,当用户与任意接触者的最新一次的接触时间超过14天时,阻断权重置为100,关联的信息不显示在社交拓扑网络中。


如图所示搜索uid为1的用户密切接触人群二级关系网络,圆圈颜色由计算的用户安全指数决定,健康显示绿色,危险显示红色,黄色介于二者之间,圆的半径与扫描到的人数成正比,边的权重为通过蓝牙RSSI衰减计算出的距离。

04

冷热分离、定期备份

因为密切接触的关系网络数据索引具有一定的时效性,对于分析密切接触的人群我们只需要14天内的索引,默认14天之外的索引数据为冷数据。针对这种情况,我们使用官方提供的索引shard分配感知将14天之外的索引移到SATA盘,降本增效。对于SSD、SATA机器节点分别打上冷热标签,索引按天建立、根据时间划分指定索引的冷热属性。


因为存储在ES上的地理区块数据索引也默认只保留14天,超过14天的索引我们采用ES官方提供的快照/恢复Snapshot/Restore API,将这些索引定期备份到HDFS上。

05

总结

目前我们这套基于 ES 空间搜索的疫情追踪分析系统已经产出三个受理专利以及两个软著,当然我们也在随着疫情政策以及个人隐私保护政策的变化改进我们的产品,也希望社区的小伙伴们可以结合 ELK stack 技术多做出一些“抗疫”产品。


正文完


作者:黄有为/张刘毅/陆峰/黄茂雷/梁立媛

中科院计算所大数据研发团队

本文编辑:筷子


嗨,互动起来吧!

喜欢这篇文章么?

欢迎留下你想说的,留言 100% 精选哦!

Elastic 社区公众号长期征稿,如果您有 Elastic  技术的相关文章,也欢迎投稿至本公众号,一起进步! 投稿请添加微信:medcl123



招聘信息

Job board

社区招聘栏目是一个新的尝试,帮助社区的小伙伴找到心仪的职位,也帮助企业找到所需的人才,为伯乐和千里马牵线搭桥。有招聘需求的企业和正在求职的社区小伙伴,可以联系微信 medcl123 提交招聘需求和发布个人简历信息。


Elastic中文社区公众号 (elastic-cn)

为您汇集 Elastic 社区的最新动态、精选干货文章、精华讨论、文档资料、翻译与版本发布等。

喜欢本篇内容就请给我们点个[在看]吧

本文分享自微信公众号 - Elastic中文社区(elastic-cn)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章