Cloudera 运营数据库提供事务支持

2021-01-08 14:16:09 浏览数 (1)

我们很高兴与大家分享在向Cloudera的Operational Database添加ANSI SQL、二级索引、星型模式和视图功能之后,我们将在接下来的几个月中引入分布式事务支持。

什么是ACID?

数据库设计的ACID模型是数据库中最重要的概念之一。ACID代表原子性、一致性、隔离性和持久性。在很长一段时间内,要成功获得商业上的数据库就必须严格遵守这四个属性。但是,这种模型在扩展到一个服务器数据库之外时会产生问题。为了适应此限制,客户扩大了部署数据库的硬件。

NoSQL数据库解耦了这4个属性中的一个或多个属性,以实现显著提高可扩展性-Cloudera运营数据库(由Apache HBase支持)就是这样的数据库。我们在原子性上进行了权衡-具体来说,Cloudera提供了单行原子性。作为补偿,我们支持非常宽的表(可能包含数百万列)。这允许客户对星型模式进行非规范化,并将其表示为单行,以便在以前表示为多个表的单行中进行原子提交。

自HBase诞生以来,我们一直致力于构建功能,以缩小与传统RDBM的功能差距,同时保持NoSQL可伸缩性、一致性、持久性和隔离性的优势。

今年早些时候,我们在Apache HBase之上提供了对ANSI SQL、二级索引、星型模式和视图的支持,为所有曾经构建过使用MySQL或PostGres的应用程序的开发人员提供了熟悉的界面和功能。

现在,我们正处于提供对跨集群中行和表的数据进行原子提交的能力的风口浪尖。

什么是ACID事务?

事务包括一组原子地管理数据库中的操作,因此所有的操作都必须要么全部完成(提交),或没有任何效果(中止)。

当前,我们仅支持单行原子事务。这意味着,当开发人员希望采用Cloudera的运营数据库时,他们需要对架构进行不同的思考。

现在,我们正在引入具有跨多个行和表的复杂事务的功能,这意味着开发人员可以根据自己的需求实施传统的星形模式或利用宽列或两者兼而有之。这种灵活性与Cloudera运营数据库的进化架构方法相结合,使开发人员可以在充分利用现有技能的同时利用现代的横向扩展数据库。

需要注意的重要一点是,Cloudera运营数据库中的事务支持是“无锁的”,并提供了快照隔离保证。传统的数据库对与事务相关联的所有数据实施“锁定”,以便其他访问数据的客户端在将数据提交到数据库之前不会对其进行更改。但是,这可能会导致竞争条件,最终导致循环依赖并挂起。锁也是导致应用程序部分性能严重下降的原因,因为应用程序相互等待,以便它们可以获取锁并继续进行操作。

我们的方法允许完成的第一个事务继续进行,而其他尝试对同一数据集进行更改的事务则必须重试。这样可以防止在数据库上同时运行的应用程序的整个生态系统变慢。换句话说,我们的方法允许线性可伸缩性,同时提供传统事务数据库能够提供的原子性。

初步性能结果

我们的事务支持功能目前处于测试阶段,并且已通过广泛的性能测试。

当前的测试包括使用OLTP Bench应用程序的行业标准TPC-C基准。TPC-C基准测试模拟了在多个仓库中同时进行的大量采购。以下实体关系图中表示了TPC-C中使用的模式:

实体块中的数字表示表的基数(行数)。这些数字由W(仓库数)所决定,以说明数据库的扩展。关系箭头旁边的数字表示关系的基数(每位父母的平均子女数)。 符号表示数据库填充数量的微小变化。

订单下达要求以下10个查询作为单个原子事务运行:

代码语言:javascript复制
1.SELECT c_discount,               
        c_last,
        C_credit
FROM   customer
WHERE  c_w_id = ?
        AND c_d_id = ?
        AND c_id = ?


2. SELECT w_tax
FROM   warehouse
WHERE  w_id = ?


3. SELECT d_next_o_id,
        D_tax
FROM   district
WHERE  d_w_id = ?
        AND d_id = ?
4. UPSERT INTO district
            (d_next_o_id,
              d_w_id,
              d_id)
SELECT d_next_o_id   1,
       d_w_id,
        D_id
FROM   district
WHERE  d_w_id = ?
        AND d_id = ?
5. UPSERT INTO new_order
            (no_o_id,
             no_d_id,
             no_w_id)
VALUES (?,?,?)


6. UPSERT INTO order
            (o_id,
             o_d_id,
             o_w_id,
             o_c_id,
             o_entry_d,
             o_ol_cnt,
             o_all_local)
VALUES (?,?,?,?, ?,?,?)
Repeat following queries for each item selected for order.


7.   SELECT i_price,
             i_name,
             i_data
      FROM   item
      WHERE  i_id = ?


 8.   SELECT s_quantity,
             s_data,
             s_dist_01,
             s_dist_02,
             s_dist_03,
             s_dist_04,
             s_dist_05,
             s_dist_06,
             s_dist_07,
             s_dist_08,
             s_dist_09,
             s_dist_10
      FROM   stock
      WHERE  s_i_id = ?
             AND s_w_id = ? 


9.   UPSERT INTO stock
           (s_quantity,
            s_ytd,
            s_order_cnt,
            s_remote_cnt,
            s_i_id,
            s_w_id)
SELECT ?,
       s_ytd   ?,
       s_order_cnt   1,
       s_remote_cnt   ?,
       s_i_id,
      s_w_id
FROM   stock
WHERE  s_i_id = ?
       AND s_w_id = ?


10.   INSERT INTO order_line
            (ol_o_id,
             ol_d_id,
             ol_w_id,
             ol_number,
             ol_i_id,
             ol_supply_w_id,
             ol_quantity,
             ol_amount,
             ol_dist_info)
VALUES      (?,?,?,?,?,?,?,?,?)

付款事务需要以下6个查询作为单个原子事务运行:

代码语言:javascript复制
1. UPSERT INTO warehouse
                  (w_ytd,
                  w_id)
      SELECT w_ytd   ?,
             w_id
      FROM   warehouse
      WHERE  w_id =?  
2. SELECT w_street_1,
       w_street_2,
       w_city,
       w_state,
       w_zip,
       w_name
FROM   warehouse
WHERE  w_id = ?


3. UPSERT INTO district
                  (d_ytd,
                  d_w_id,
                  d_id)
      SELECT d_ytd   ?,
             d_w_id,
             d_id
      FROM   district
      WHERE  d_w_id = ?
             AND d_id = ? 
4. SELECT d_street_1,
             d_street_2,
             d_city,
             d_state,
             d_zip,
             d_name
      FROM   district
      WHERE  d_w_id = ?
             AND d_id = ? 
6. UPSERT INTO customer
            (c_balance,
            c_ytd_payment,
            c_payment_cnt,
            c_w_id,
            c_d_id,
           c_id)
SELECT ?,
      ?,
      ?,
       c_w_id,
       c_d_id,
      c_id
FROM   customer
WHERE  c_w_id = ?
       AND c_d_id = ?
       AND c_id = ?  
7. INSERT INTO history
            (h_c_d_id,
             h_c_w_id,
             h_c_id,
             h_d_id,
             h_w_id,
             h_date,
             h_amount,
            h_data)
VALUES      (?,?,?,?,?,?,?,?)

通过在Dell PowerEdge R440节点上运行3台区域服务器,我们可以获得以下结果:

在此图中,Y轴表示每分钟可以完全处理(包括新订单创建,付款,交付等)的订单数量,并以tpm-C基准表示。X轴表示并行执行事务的实体的数量。

这些初步结果表明,该系统达到了150到300个事务处理程序之间的峰值事务吞吐量,需要进一步测试才能确定该峰值。

随着此功能的成熟,OpDB吞吐量和我们测量吞吐量的能力都将提高。

结论

大多数应用程序利用事务来支持企业面临的各种需求。但是,当传统的RDBMS无法扩展时,客户被迫手动分片数据库,并将每个分片数据库作为独立的数据库进行管理。

当这变得太麻烦而无法管理时,客户应考虑将该应用程序迁移到Cloudera的运营数据库。复杂的事务支持与ANSI SQL支持以及Apache HBase的横向扩展特性相结合,提供了可以显着降低管理增长的操作复杂性的组合。

如果您厌倦了管理分片数据库并希望降低数据库的总拥有成本,请与您的Cloudera客户团队联系,以寻求我们的帮助。

原文作者:Krishna Maheshwari& Rajeshbabu Chintaguntla

原文链接:https://blog.cloudera.com/bringing-transaction-support-to-cloudera-operational-database/

0 人点赞