写点什么

2G 内存搞定一亿数据的分析引擎

作者:Western Panda
  • 2023-11-21
    天津
  • 本文字数:2405 字

    阅读完需:约 8 分钟

2G内存搞定一亿数据的分析引擎

运行大数据服务对服务器的配置要求是比较高的,相应的经济成本也不会低。本人做数据分析相关工作,一直在寻找高性能低成本的开源 OLAP 引擎,但是并没有找到,既然这样,那就自己搞一个。

EuclidOLAP

EuclidOLAP 是我搞的一个开源 OLAP 多维数据库,它目前具有以下的几个特点:


  • 针对百亿级别数据量查询时可以达到毫秒级响应;

  • 能够支持非常复杂的查询,包括跨模型的关联查询;

  • 支持实时的增删改查;

  • 可以部署为集群模式,也能以单机模式运行在低配置服务器上。


在将来 EuclidOLAP 将会演化成基于云原生、容器、弹性资源的存算分离的架构模式。


EuclidOLAP 的 Github 地址:https://github.com/EuclidOLAP/EuclidOLAP


剩下的内容分为两部分,首先简要介绍一下 EuclidOLAP 的数据模型与存储结构,然后在一台 3G 内存的低配服务器上运行一个 EuclidOLAP 示例并对一个一亿数据量的模型进行分析。

数据模型与存储结构

EuclidOLAP 采用了立方体(Cube)和维度(Dimension)作为数据模型,如下所示:



维度就相当于坐标轴,你可以将一个关联个 N 个维度的 Cube 想象成一个 N 维立方体,同时把所有度量值想象成是存储于一个多维数组中。多维数组结构会带来一个严重的问题——内存容量爆炸,为了解决这个问题,像 Cogons、Essbase 这些传统多维数据库的解决办法是采用稀疏维和密集维结构:稀疏的几个维度被构建为索引,密集的维度则被构建为数据块——相对密集的更小的多维数组。



由于根据密集维构成的数据块也会存在数据空洞,所以上述的这种数据结构也会浪费掉一些内存。


EuclidOLAP 的解决办法是在多维数组元素前面添加坐标偏移量,然后进行完全压缩,这样虽然也需要额外的内存来存储偏移量数据,但其消耗的内存相对于前面那两种结构来说是可以忽略不计的。



EuclidOLAP 会同时构建一个索引结构,它会根据数据偏移量进行快速定位,以确定度量数据的坐标和聚合查询时的数据范围。


在逻辑层面,EuclidOLAP 的这个索引结构很像图-2 中稀疏维索引,但不同之处在于 EuclidOLAP 的这个索引结构可以表示从全部稀疏维到全部密集维的各种情况,我给它起了个名字——弹性索引结构。


在一个关联个 N 个维度的 Cube 中,弹性索引可以表示 N+1 种索引结构:



在逻辑模型层面,你还是可以将 EuclidOLAP Cube 中的度量数据想象成是存储于一个有着大量数据空洞的巨大的多维数组之中。


这种弹性索引结构同样存在问题,在新增数据时会导致整个数据结构的变化,我会在以后的文章中专门来介绍针对这个问题的解决办法。


接下来进入实践环节。

运行 EuclidOLAP 服务实例

EuclidOLAP 中自带了一个一亿数据量的 Cube,它需要占用不到 2G 内存,我在一台 2400M 内存的机器上运行过,你需要准备一台 CentOS、Redhat、Ubuntu 或 Debian 服务器,内存最好不低于 3G。


EuclidOLAP 自带了一个名为 Nile Online Store 的 Cube,它关联了六个维度:日期(Date )、地区(Region )、商品(Goods )、支付方式(Payment Methods )、客户类型(Customer Types )、销售渠道(Sales Channels )。


点击这个链接查看这 6 个维度的详细结构:http://www.euclidolap.com/attachments/nos.html


这个 Cube 有一个度量值:Sales,为了演示方便,所有的明细度量值都是 1。



EuclidOLAP 支持多维数据库的标准语言——MDX(Multi-Dimensional Expressions ),它在语法结构上类似于 SQL,不同之处在于 MDX 在语义层面直接描述多维结构,它对于复杂分析的支持能力要强于 SQL。


按下面的步骤下载并运行 EuclidOLAP 服务:


wget https://sysbase.oss-cn-beijing.aliyuncs.com/EuclidOLAP-v0.1.6.1.tar.gztar zxvf EuclidOLAP-v0.1.6.1.tar.gzcd EuclidOLAP./bin/start.sh &
复制代码


查看日志:


tail -n 5 log/euclid.log
复制代码



当日志中显示了 Net service startup on port 8760 内容时表示 EuclidOLAP 已经成功运行。

第一个 MDX 是一个执行全汇总的查询

select    [Measures].Sales on 0,    Date.[ALL] on 1from [Nile Online Store];
复制代码


在 EuclidOLAP 目录中运行 olap 客户端工具:


./bin/olap-cli
复制代码


执行 MDX 查询:



这个查询将全部明细数据汇总查出,结果是 100000000。

第二个 MDX 对明细数据进行查询

它在商品维度(Goods )、支付方式维度(Payment Methods )、客户类型维度(Customer Types )和销售渠道维度(Sales Channels )上进行了限定,然后按日期维度(Date )和地区维度(Region )查看 Sales 度量值:


select    {Date.[2022].Q1, Date.[2022].Q2, Date.[2022].Q3, Date.[2022].Q4} on 0,    {Region.Europe.France, Region.Europe.Germany, Region.Europe.[United Kingdom]} on 1from [Nile Online Store]where([Goods].[Foodstuff].[Drink].[Tea], [Payment Methods].[PayPal], [Customer Types].[New customers], [Sales Channels].[Direct sales]);
复制代码


执行这个 MDX 将立即返回结果。


第三个 MDX 与第二个类似

它没有在日期和地区之外的其他维度进行限定,该查询将在其他四个维度上进行汇总。日期和地区维度分别指定了年份和洲级别的维度成员,这要比第二个 MDX 具有更高的汇总粒度。


select    {Date.[2020], Date.[2021], Date.[2022]} on 0,    {Region.Asia, Region.Europe, Region.[North America]} on 1from [Nile Online Store];
复制代码


第四个 MDX 是一个复杂逻辑的查询

它将按地区查询 2022 年总体销售额最高的那个季度的前三种畅销商品的销售数据:


select    CrossJoin(        TopCount(Date.[2022].Children, 1, [Measures].Sales),        TopCount(LateralMembers([Goods].[Foodstuff].[Drink].[Tea]), 3, [Measures].Sales)) on 1,Region.ROOT.Children() on 0from [Nile Online Store];
复制代码



最后说一下 MDX 这个东西。MDX 与 SQL 语法相似,如同 SQL 查询一样,每个 MDX 查询都要求有 SELECT、FROM 和可选的 WHERE 部分。SQL 的语义模型描述 Table 结构,MDX 的语义模型描述 Cube 结构,相同的一套业务模型可以放在 SQL 星型表结构中,也可以放在 MDX Cube 模型中,但是基于 Cube 使用 MDX 能更好的支持复杂且比 SQL 更加直观。关于 MDX 的详细介绍我也会发布在以后的文章中。


用户头像

Western Panda

关注

还未添加个人签名 2023-10-30 加入

还未添加个人简介

评论

发布
暂无评论
2G内存搞定一亿数据的分析引擎_数据库_Western Panda_InfoQ写作社区