海量数据查询方案设计

2024-07-06 18:27:44 浏览数 (3)

原始数据的数据量太大了,能存下来就很不容易了,这个数据是没法直接来给业务系统查询和分析的:

  • 数据量太大了
  • 也没有很好的数据结构和查询能力,来支持业务系统查询

一般用流计算或批计算,把原始数据再进行一次或多次过滤、汇聚和计算,把计算结果落到另外一个存储系统,由这存储再给业务系统提供查询支持。“流计算”指Flink、Storm实时计算,批计算是Map-Reduce或Spark非实时计算。

像点击流、监控和日志这些原始数据是“海量数据中的海量数据”,这些原始数据经过过滤汇总和计算之后,大多数情况下数据量会有量级下降,如从TB级别的数据量,减少到GB级别。

有的业务,计算后的数据非常少,如按天粒度的汇总数据或排行榜类数据,用什么存储都能满足要求。有些业务没法通过事先计算的方式解决全部的问题。原始数据经过计算后产生的计算结果,数据量相比原始数据会减少一些,但仍然是海量数据。还要在这个海量数据上,提供性能可以接受的查询服务。

1 分析类系统如何选择存储?

查询海量数据的系统,大多都是离线分析类系统,你可以简单地理解为类似于做报表的系统,也就是那些主要功能是对数据做统计分析的系统。这类系统是重度依赖于存储的。选择什么样的存储系统、使用什么样的数据结构来存储数据,直接决定了数据查询、聚合和分析的性能。

分析类系统对存储的需求:

  • 用于分析的数据量比在线业务大出几个数量级,这需要存储系统能保存海量数据
  • 能在海量的数据上做快速聚合、分析和查询。“快速”前提是处理GB、TB甚至PB级海量数据,在这么大的数据量上做分析,几十s甚至几min都算很快,和在线业务要求的毫秒级速度不一样
  • 由于数据大多异步写入,对写入性能和响应时延要求不高
  • 分析类系统不直接支撑前端业务,所以也不要求高并发

存储产品

如果你的系统的数据量在GB量级下,MySQL仍可考虑,查询能力足以应付大部分分析系统的业务需求。并可和在线业务系统合用一个数据库,不用做ETL(数据抽取),省事且实时性好。最好给分析系统配置单独的MySQL实例,避免影响线上业务。

数据量级超过MySQL极限,可选列式数据库,如HBase、Cassandra、ck,对海量数据有很好查询性能,正确使用,10GB量级数据查询基本s级返回。高性能代价是功能缩水,这些DB对数据的组织方式都有限制,查询方式没MySQL灵活。

另一选择ES本是为搜索而生的存储,但也支持结构化数据存储和查询。由于其数据都存储在内存,且支持类似Map-Reduce分布式并行查询,所以对海量结构化数据的查询性能也好。

ES对数据组织方式和查询方式的限制,没有其他列式数据库那么死板。即ES的查询能力和灵活性是要强于上述这些列式数据库的。优先考虑ES。但是ES有一个缺点,就是你需要给它准备大内存的服务器,硬件成本有点高。

数据量级超过TB级的时候,对这么大量级的数据做统计分析,无论使用什么存储系统,都快不到哪儿去。这个时候的性能瓶颈已经是磁盘IO和网络带宽了。这种情况下,实时的查询和分析肯定做不了。解决的办法都是,定期把数据聚合和计算好,然后把结果保存起来,在需要时对结果再进行二次查询。这么大量级一般选择保存在HDFS中,配合Map-Reduce、Spark、Hive等等这些大数据生态圈产品做数据聚合和计算。

根据查询选择存储系统

面对海量数据,仅根据数据量级选择存储系统远不够。“我的系统,每天都产生几个GB的数据量,现在基本已经慢得查不出来了,你说我换个什么DB能解决?”对不起,换什么数据库也解决不了你的问题。为什么这么说?

过去几十年,存储技术和分布式技术,在基础理论方面并没有本质突破。技术发展更多的是体现在应用层,如集群管理简单,查询更自动化,像Map-Reduce这些。不同的存储系统之间,并没有本质的差异。它们的区别只是,存储引擎的数据结构、存储集群的构建方式,以及提供的查询能力,这些方面的差异。这些差异,使得每一种存储,在它擅长的一些领域或者场景下,会有很好性能表现。

如RocksDB、LevelDB,它们的存储结构LSM-Tree,就是日志和跳表组合,从数据结构时间复杂度,和MySQL的B 树有本质提升吗?没有,都是O(log n)。但LSM-Tree某些情况下利用日志有更好的写性能。没有哪种存储能在所有情况下,都有明显性能优势。

存储系统没有银弹,不要指望简单更换一种DB,就解决数据量大,查询慢问题。但特定场景通过一些优化方法,把查询性能提升几十倍甚至几百倍都有可能。根据查询来选择存储系统和数据结构。用ES构建商品搜索系统就是把这个思想实践好案例。ES倒排索引没有比B 树更快或先进,但面对“全文搜索”查询需求,倒排索引就比其他存储系统和数据结构,性能高几十倍。

智能补货系统,根据历史物流数据,对未来预测,给全国每个仓库补货。做到你下单买的商品,很大概率在离你家几公里那个京东仓库里就有货,很快就送到。这个系统的背后,它需要分析每天几亿条物流数据,每条物流数据又细分为几段到几十段,那每天的物流数据就是几十亿的量级。

这份物流数据,它的用途也非常多,如智能补货系统要用;调度运力的系统也要用;评价每个站点儿、每个快递小哥的时效达成情况,还要用这个数据;物流规划人员同样要用这个数据进行分析,对物流网络做持续优化。

什么样的存储系统保存这些物流数据,才能满足这些查询需求?任何一种存储系统都满足不了这么多种查询需求。要根据每一种需求专门选择合适存储系统,定义适合数据结构,各自解决各自的问题。而不是用一种数据结构,一个数据库去解决所有问题。

对于智能补货和运力调度这两个系统,区域性很强,可把数据按照区域(省或者地市)分片,再汇总一份全国的跨区物流数据,绝大部分查询都可落在一个分片上,查询性能很好。

对站点和人的时效达成情况,这种业务的查询方式以点查询为主,考虑事先在计算时,按站点和人把数据汇总好,存放到一些分布式KV存储,做到毫秒级查询性能。

物流规划的查询需求多变,可将数据放到Hive表,按时间分片,是对查询最友好的分片方式。物流规划人员可在上面执行分析类查询任务,一个查询任务即使是花几h,验证一个新的规划算法,也可接受。

总结

海量数据的主要用途,就是支撑离线分析类业务的查询,根据数据量规模不同,由小到大可选:关系型数据库,列式数据库和一些大数据存储系统。TB量级下数据,若可接受相对较贵的硬件成本,ES很好。

对于海量数据来说,存储系统无银弹,重要的是思想,根据业务对数据查询方式,反推数据应该使用什么存储系统、如何分片,以及如何组织。即使是同样一份数据,也要根据不同的查询需求,组织成不同的数据结构,存放在适合的存储系统中,才能在每一种业务中都达到理想的查询性能。

FAQ

Q:日志系统,收集全公司所有系统的全量程序日志,给开发和运维提供日志查询和分析服务,选啥存储系统?

选择 ES,因为:

  • 日志一般是根据时间线来保存的,而且不用保存历史的数据,只需保存最近 15天或 7天数据,数量不是很大
  • 查看日志时,一般都会使用全文搜索, ES 可高效支持

Q:为啥 Kafka 能做到几倍于 HDFS 吞吐能力,技术根本原因是啥?

A:对于磁盘,顺序读写性能要远高于随机读写,性能差距视不同磁盘,大约在几十倍左右。Kafka是为顺序读写设计,HDFS是为随机读写设计,所以顺序写入时,Kafka性能更好。

Q:内存数据库疑问:启动后他会把放到硬盘的数据放到内存里?还是查询过一次之后把结果放到内存里?

A:启动之后他会把放到硬盘的数据放到内存。

Q:ES作为分布式内存数据库,咋理解?ES并没有像Redis一样,把所有数据都存储在内存吧?ES是“可靠的”存储,而Redis是“不可靠的”存储。

A:ES (Elasticsearch) 作为分布式内存数据库的理解有一些误区。确实,ES并不像Redis那样将所有数据都存储在内存中。我们可以通过以下几个方面来理解这个问题:

1. 数据存储机制

Elasticsearch (ES)

  • 磁盘存储:ES主要将数据存储在磁盘上,虽然会利用内存进行缓存和提高查询速度,但核心数据存储仍然依赖磁盘。这使得ES能够处理大量的数据而不会因为内存不足而受限。
  • 缓存机制:ES利用内存缓存来加速查询,例如通过操作系统的页面缓存、ES自己的缓存等,这样可以减少磁盘I/O操作,提高查询效率。

Redis

  • 内存存储:Redis是一个内存数据库,数据主要存储在内存中,这使得Redis具有极高的读写性能。但是这种方式也意味着数据量受到内存大小的限制。
  • 持久化:虽然Redis可以通过RDB快照和AOF日志来实现数据持久化,但其主要设计目标是作为内存数据库使用。

2. 数据可靠性

Elasticsearch

  • 高可靠性:由于ES将数据存储在磁盘上,并通过分片和副本机制来确保数据的高可用性和可靠性。即使某个节点发生故障,其他节点的副本数据仍然可用。
  • 数据恢复:ES具有强大的数据恢复能力,可以在节点故障后重新分配和恢复数据。

Redis

  • 不可靠存储:由于主要依赖内存存储,Redis在节点故障时数据可能会丢失,特别是在未进行持久化配置或在持久化过程中发生故障时。
  • 持久化选项:通过RDB和AOF持久化机制,Redis可以提供一定程度的数据可靠性,但这仍然取决于配置和具体使用场景。

3. 使用场景

Elasticsearch

  • 全文搜索和分析:ES适用于需要复杂查询、全文搜索和实时数据分析的场景,例如日志分析、产品搜索引擎等。
  • 大数据量处理:由于其数据存储在磁盘上,ES可以处理TB级别甚至PB级别的大数据集。

Redis

  • 高速缓存:适用于需要极高读写性能的场景,例如缓存数据库查询结果、会话存储等。
  • 计数器和排行榜:在需要快速计数和排名的场景中,Redis的内存存储优势明显。

综上所述,虽然ES在某些场景下也使用内存来提高性能,但其本质上是一个磁盘存储为主的数据库,与Redis这种完全依赖内存存储的数据库有本质区别。因此,称ES为“分布式内存数据库”是不准确的。

Q:数据量没到PB时直接用ES,再大估计得用MR,但MR会不会太慢?

A:这时性能瓶颈已是网络和磁盘IO。MR的“慢”也是相对,当查询数据量足够大时,MR性能还非常不错。

0 人点赞