初见 ByConity

121 阅读8分钟

最近也在学习数据处理方面的知识,发现随着数据量越来越大,数据也变得越来越复杂。好多企业都开始用上 OLAP(联机分析处理)引擎来对付大规模数据了,还能立马给出分析结果,挺牛的。之前只了解过ClickHouse,这次又看到社区众测ByConity,也就来试试,目前有4种主流的开源 OLAP,分别是 ByConity、ClickHouse、Doris和Presto 。

ClickHouse 是俄罗斯的搜索引擎公司 Yandex 开发出来的一个数据库管理系统,它是列式的。这个系统主要就是针对大规模数据,能让你快速地进行查询和分析。Doris 是一个分布式的列式存储和分析系统。它厉害的地方在于支持实时查询和分析。ByConity 是字节跳动开源的云原生数据仓库,可以满足用户的多种数据分析场景。它用了存储计算分离的架构,能做到租户资源隔离、弹性扩缩容,还有数据读写的强一致性这些特性呢。它支持主流的 OLAP 引擎优化技术,读写性能那是相当棒。

开始测试

测试环境

测试步骤

由于我用的是window11,系统也是包含了基于 OpenSSH(一个使用 SSH 协议进行远程登录的连接工具)的内置 SSH 服务器和客户端。我们可以在设置中找到系统,系统里包含了可选功能,如图所示:

开始登陆

在本地电脑桌面按win+r,然后输入cmd,弹出终端。然后在终端输入以下命令:

ssh -p 23 <提供的用户名>@<ECS服务器IP地址>

例如:ssh -p 23 root@14.103.145.182

第一次登陆会弹出:我们输入yes确认就行

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

然后输入<提供的登录密码>并回车。我登录的时候输了好几次,就是登陆不上,粘贴复制和手输都尝试了,死活登录不上😡,如果是复制了密码,回到终端,必须鼠标左单击一次,再右单击一次才能输入密码,最后登陆成功。

如果显示如上图,那就说明已经登陆成功了。

根据测试文档,为避免使用时超时自动断开连接,我们可以运行如下命令:

tmux new -s $user_id

例如:tmux new -s user001

注:$user_id是可以自定义的会话名称

接着,我们运行如下命令进入客户端 :

clickhouse client --port 9010

如图:

测试sql78

首先我测试的是sql78,

with ws as
        (select d_year AS ws_sold_year, ws_item_sk,
        ws_bill_customer_sk ws_customer_sk,
        sum(ws_quantity) ws_qty,
        sum(ws_wholesale_cost) ws_wc,
        sum(ws_sales_price) ws_sp
        from web_sales
        left join web_returns on wr_order_number=ws_order_number and ws_item_sk=wr_item_sk
        join date_dim on ws_sold_date_sk = d_date_sk
        where wr_order_number is null
        group by d_year, ws_item_sk, ws_bill_customer_sk
        ),
        cs as
        (select d_year AS cs_sold_year, cs_item_sk,
        cs_bill_customer_sk cs_customer_sk,
        sum(cs_quantity) cs_qty,
        sum(cs_wholesale_cost) cs_wc,
        sum(cs_sales_price) cs_sp
        from catalog_sales
        left join catalog_returns on cr_order_number=cs_order_number and cs_item_sk=cr_item_sk
        join date_dim on cs_sold_date_sk = d_date_sk
        where cr_order_number is null
        group by d_year, cs_item_sk, cs_bill_customer_sk
        ),
        ss as
        (select d_year AS ss_sold_year, ss_item_sk,
        ss_customer_sk,
        sum(ss_quantity) ss_qty,
        sum(ss_wholesale_cost) ss_wc,
        sum(ss_sales_price) ss_sp
        from store_sales
        left join store_returns on sr_ticket_number=ss_ticket_number and ss_item_sk=sr_item_sk
        join date_dim on ss_sold_date_sk = d_date_sk
        where sr_ticket_number is null
        group by d_year, ss_item_sk, ss_customer_sk
        )
        select
        ss_sold_year, ss_item_sk, ss_customer_sk,
        round(ss_qty/(coalesce(ws_qty,0)+coalesce(cs_qty,0)),2) ratio,
        ss_qty store_qty, ss_wc store_wholesale_cost, ss_sp store_sales_price,
        coalesce(ws_qty,0)+coalesce(cs_qty,0) other_chan_qty,
        coalesce(ws_wc,0)+coalesce(cs_wc,0) other_chan_wholesale_cost,
        coalesce(ws_sp,0)+coalesce(cs_sp,0) other_chan_sales_price
        from ss
        left join ws on (ws_sold_year=ss_sold_year and ws_item_sk=ss_item_sk and ws_customer_sk=ss_customer_sk)
        left join cs on (cs_sold_year=ss_sold_year and cs_item_sk=ss_item_sk and cs_customer_sk=ss_customer_sk)
        where (coalesce(ws_qty,0)>0 or coalesce(cs_qty, 0)>0) and ss_sold_year=2000
        order by
        ss_sold_year, ss_item_sk, ss_customer_sk,
        ss_qty desc, ss_wc desc, ss_sp desc,
        other_chan_qty,
        other_chan_wholesale_cost,
        other_chan_sales_price,
        ratio
        LIMIT 100;

测试结果如下:

执行完成后,显示具体内容如下:

  1. 数据集规模:数据集中有 100 行数据。
  2. 处理时间:处理这些数据花费了 55.520 秒。
  3. 处理的数据量:总共处理了 504.21 百万行数据。
  4. 数据处理速率:处理速度为每秒 6.05 GB(千兆字节)。换算成每秒处理的行数是 9.08 百万行。每秒处理的数据量为 103.94 MB(兆字节)。

测试sql64

with cs_ui as
        (select cs_item_sk
        ,sum(cs_ext_list_price) as sale,sum(cr_refunded_cash+cr_reversed_charge+cr_store_credit) as refund
        from catalog_sales
        ,catalog_returns
        where cs_item_sk = cr_item_sk
        and cs_order_number = cr_order_number
        group by cs_item_sk
        having sum(cs_ext_list_price)>2*sum(cr_refunded_cash+cr_reversed_charge+cr_store_credit)),
        cross_sales as
        (select i_product_name product_name
        ,i_item_sk item_sk
        ,s_store_name store_name
        ,s_zip store_zip
        ,ad1.ca_street_number b_street_number
        ,ad1.ca_street_name b_street_name
        ,ad1.ca_city b_city
        ,ad1.ca_zip b_zip
        ,ad2.ca_street_number c_street_number
        ,ad2.ca_street_name c_street_name
        ,ad2.ca_city c_city
        ,ad2.ca_zip c_zip
        ,d1.d_year as syear
        ,d2.d_year as fsyear
        ,d3.d_year s2year
        ,count(*) cnt
        ,sum(ss_wholesale_cost) s1
        ,sum(ss_list_price) s2
        ,sum(ss_coupon_amt) s3
        FROM   store_sales
        ,store_returns
        ,cs_ui
        ,date_dim d1
        ,date_dim d2
        ,date_dim d3
        ,store
        ,customer
        ,customer_demographics cd1
        ,customer_demographics cd2
        ,promotion
        ,household_demographics hd1
        ,household_demographics hd2
        ,customer_address ad1
        ,customer_address ad2
        ,income_band ib1
        ,income_band ib2
        ,item
        WHERE  ss_store_sk = s_store_sk AND
        ss_sold_date_sk = d1.d_date_sk AND
        ss_customer_sk = c_customer_sk AND
        ss_cdemo_sk= cd1.cd_demo_sk AND
        ss_hdemo_sk = hd1.hd_demo_sk AND
        ss_addr_sk = ad1.ca_address_sk and
        ss_item_sk = i_item_sk and
        ss_item_sk = sr_item_sk and
        ss_ticket_number = sr_ticket_number and
        ss_item_sk = cs_ui.cs_item_sk and
        c_current_cdemo_sk = cd2.cd_demo_sk AND
        c_current_hdemo_sk = hd2.hd_demo_sk AND
        c_current_addr_sk = ad2.ca_address_sk and
        c_first_sales_date_sk = d2.d_date_sk and
        c_first_shipto_date_sk = d3.d_date_sk and
        ss_promo_sk = p_promo_sk and
        hd1.hd_income_band_sk = ib1.ib_income_band_sk and
        hd2.hd_income_band_sk = ib2.ib_income_band_sk and
        cd1.cd_marital_status <> cd2.cd_marital_status and
        i_color in ('purple','burlywood','indian','spring','floral','medium') and
        i_current_price between 64 and 64 + 10 and
        i_current_price between 64 + 1 and 64 + 15
        group by i_product_name
        ,i_item_sk
        ,s_store_name
        ,s_zip
        ,ad1.ca_street_number
        ,ad1.ca_street_name
        ,ad1.ca_city
        ,ad1.ca_zip
        ,ad2.ca_street_number
        ,ad2.ca_street_name
        ,ad2.ca_city
        ,ad2.ca_zip
        ,d1.d_year
        ,d2.d_year
        ,d3.d_year
        )
        select cs1.product_name
        ,cs1.store_name
        ,cs1.store_zip
        ,cs1.b_street_number
        ,cs1.b_street_name
        ,cs1.b_city
        ,cs1.b_zip
        ,cs1.c_street_number
        ,cs1.c_street_name
        ,cs1.c_city
        ,cs1.c_zip
        ,cs1.syear
        ,cs1.cnt
        ,cs1.s1 as s11
        ,cs1.s2 as s21
        ,cs1.s3 as s31
        ,cs2.s1 as s12
        ,cs2.s2 as s22
        ,cs2.s3 as s32
        ,cs2.syear
        ,cs2.cnt
        from cross_sales cs1,cross_sales cs2
        where cs1.item_sk=cs2.item_sk and
        cs1.syear = 1999 and
        cs2.syear = 1999 + 1 and
        cs2.cnt <= cs1.cnt and
        cs1.store_name = cs2.store_name and
        cs1.store_zip = cs2.store_zip
        order by cs1.product_name
        ,cs1.store_name
        ,cs2.cnt
        ,cs1.s1
        ,cs2.s1;

执行结果:

开始拉取数据

这张图片展示了一组数据处理的统计信息。具体内容如下:

  1. 数据集规模:数据集中有11492行数据。
  2. 处理时间:处理这些数据花费了83.548秒。
  3. 处理的数据量:总共处理了536.09千行数据。
  4. 数据处理速率:处理速度为每秒14.33 MB(兆字节)。换算成每秒处理的行数是6.42千行。每秒处理的数据量为171.49 KB(千字节)。

接着我们添加在sql64中添加一下限制,在执行成功的查询中,添加参数限制查询的最大内存使用量,如:

SETTINGS``max_memory_usage=40000000000;(单位为 B,当前约合 37.25 GB)

  • SETTINGS max_memory_usage=28000000000;

测试结果:

这张图片展示了一组数据处理的相关统计信息:

  1. 数据集中有 11492 行数据。
  2. 处理这些数据花费了 5.796 秒。
  3. 总共处理了 536.09 千行数据。
  4. 处理速度为每秒 14.33 MB(兆字节),换算成每秒处理的行数是 92.49 千行,每秒处理的数据量为 2.48 MB。
  • SETTINGS max_memory_usage=19600000000;

测试结果:

这张图片展示了一组数据处理的统计信息:

  1. 数据集中有 11492 行数据。
  2. 处理这些数据花费了 5.741 秒。
  3. 总共处理了 536.00 千行数据。
  4. 处理速度为每秒 14.33 MB(兆字节),换算成每秒处理的行数是 93.38 千行,每秒处理的数据量为 2.50 MB。

ByConity 和 ClickHouse

我之前用过ClickHouse,通过这次测试想聊聊优缺点,ByConity 是基于 ClickHouse 内核研发的开源云原生数据仓库,采用存算分离的架构。它们两个写入速度都是非常快的,适用于大量数据的写入,其次查询速度非常快,在海量数据下,查询速度可达2-30GB/s,另外数据压缩比高,存储成本低,压缩比可达 0.2~0.3。ByConity 具备 ClickHouse 的诸多优点,并且与 ClickHouse 保持着良好的兼容性。同时,ByConity 在读写分离、弹性扩缩容以及数据强一致等方面进行了显著增强。

我觉得ByConity是ClickHouse 的增强版,ClickHouse 缺点也很明显,ClickHouse扩容非常麻烦,而且扩容后需要从新进行数据分布。另外运维也很麻烦,尤其是高峰期的时候,又不能快速扩容,它一般通过删减其它业务数据才能得到缓冲,所以它查询就会变得很慢。