`
大涛学长
  • 浏览: 105141 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

为了实现在线库的复杂查询,你还在双写吗?

阅读更多
一、在线库不支持在线复杂查询
--------------

做在线业务的开发者经常会碰到这样的难题:在线数据库上面运行稍微复杂点的查询,在线业务就挂了!不管是单机数据库如MySQL、PG,还是分布式数据库,HBase、MongoDB、Cassandra都有这个问题。下面,本文就以HBase为例对该问题进行说明,其他库原理类似。

HBase作为海量在线存储引擎,被广泛应用于推荐、风控、物联网、画像、表单等大数据场景。Phoenix作为HBase的SQL层,极大降低了用户使用门槛,并且实现了二级索引、加盐表、动态列等大量实用功能。HBase底层存储基于LSM,LSM能将业务的随机写转为顺序写,能有效提升写吞吐,但是其查询只适合于Rowkey的前缀匹配,查询模式单一;Phoenix二级索引,底层是跟原表关联的索引表,同样也是前缀匹配,一个表可以有多个索引,这样可以增加查询模式,但是索引数目不能太多,否则写放大的问题会比较严重。

对于更加复杂的查询场景,比如表单、日志查询里面的模糊查找,用户画像里面的随机条件组合等等,HBase + Phoenix的组合就不能支持。该问题是基于LSM的NoSQL在线数据库的通用问题,除了HBase,Cassandra、LevelDB、RocksDB、MongoDB引擎等都有相同的问题。

有开发者选择在备库上做复杂查询,不过前面提到在线库本身的查询能力往往有限,要么很慢,要么就查不出来,满足不了在线复杂查询的实时性要求。

二、双写遇到的问题
---------

![fa262e46a23c98a0921fe3a9b545fa00a33eb882.png](https://ucc.alicdn.com/pic/developer-ecology/9946b6d76d514853ad798402776103f0.png)

为了解决问题1,用户自然会想到借助检索引擎,比如ES、Solr、Lucene等来解决该问题。不少用户选择的是双写的方式,也就是每一条记录同时写在线库和检索引擎,该方式看起来简单,但实际使用过程中问题很多。我们了解到的case,把这套方案解决较好的客户往往都是要投入月级别的时间和大量人力。下面以双写HBase和Solr为例,举几个用户遇到比较多的问题。

*   一致性难以保证

双写很难保证在线库跟检索引擎的一致性。比如,两个链接并发双写,并且有修改的操作,那么很难保证HBase中同一字段的写入顺序跟Solr中同一个doc的修改顺序一致,那HBase和Solr中数据就出现了不一致,而且出现问题很难排查;另外,在线库往往只需要保存最近一段时间的数据,超过TTL的数据会被自动清理掉,而Solr中同样会有这个需求。但是HBase是按照KV做TTL的,Solr是按照doc,那两者在做数据清理的时候同样会出现不一致。不一致的场景有很多,这里就不一一介绍了。

*   写入性能下降

相同配置下,HBase的吞吐要比Solr高很多,这源于软件设计的出发点不同,优化的方向不同等诸多因素。如果双写,那势必会导致Solr的写吞吐限制了HBase的写吞吐。

*   历史数据的同步

双写只是解决了新数据的问题,对于历史数据则不适用,用户需要自己解决历史数据批量同步问题。特别是,对于不能停机的场景,在历史数据rebuild过程中,如何解决跟新数据跟历史数据相互覆盖的问题,也是十分棘手的问题。

*   冗余存储空间

检索引擎专门解决索引问题,其数据存储格式要比在线库要更复杂,一份在线库的数据在检索引擎中可能需要存储多份,比如原始数据存储,倒排索引存储,为提升聚合和排序的列存DocValue的存储。那么,势必有存储冗余的问题,如何降成本也是一大挑战。

*   稳定性

双写要求HBase和Solr同时保证稳定性,如果Solr出现故障,写流程会被block住,对在线业务造成影响。

三、HBase + Solr易用性不足
-------------------

阿里云HBase Solr全文检索引擎,采用在系统层做数据转换和同步的方式一站式解决了用户使用双引擎遇到的大部分问题。但是,试用过的用户会有一个体会,就是使用太灵活了,步骤也比较繁琐,容易出问题,如果不是资深玩家难以驾驭。下面举几个用户痛点:

*   使用门槛高

用户需要同时理解HBase、Solr、Indexer(数据同步服务),同时操作HBase Shell,Indexer命令行,Solr界面三个途径才能把流程走通。

*   Schemaless的HBase跟强Schema的Solr数据类型 
    难以保证对齐

首先,用户要自己定义从HBase column到Solr field的映射;其次,用户要自己保证实际写入到HBase中的类型正确。比如HBase中一个列对应Solr中一个long类型,因为HBase API并不检查用户实际写入的数值是否合法,导致写入HBase成功,但是同步到Solr是通不过的。这就要求用户要自己基于HBase API写一套类型检查系统,费时费力。

*   HBase + Solr对于数据冗余存储的问题解决不友好

用户需要自己决定Solr中是否开启stored,docValued选项,对于只开启indexed选项的Field,用户可以通过回读HBase的方式来拿到最终结果数据,而对于开启了stored或者docValued的Field,直接从Solr中返回结果性能会更好。这套优化的逻辑需要用户自己管理和实现。

四、SearchIndex灵活易用一体化在线库引擎
-------------------------

![架构.png](https://ucc.alicdn.com/pic/developer-ecology/18a796107e4b41ebae66a8a76ca6915e.png)

SearchIndex是阿里云HBase SQL(Phoenix)基于HBase + Solr双引擎的新的索引实现,其架构如上图所示。Phoenix层将SQL(DDL、DML)语句转化为对HBase和Solr的具体操作,SearchService负责索引同步,一致性,元数据管理等。 
SearchService内部会统一管理HBase中TimeStamp和Solr中DocVersion的对应关系,来实现最终一致性。简单来说,Solr一行数据的DocVersion等于当前已被同步的HBase对应行各个column的TimeStamp最大值,在解决乱序时,如果前面新的cell已经被同步了,老的cell则被直接丢掉即可。而对于TTL问题,我们实现了基于行的HBase Compaction机制,来保证一致性。

SearchIndex解决了前面提到的所有问题,用户只需要几分钟,几条SQL语句就可以跑通整个流程,可参考[快速开始文档](https://yq.aliyun.com/go/articleRenderRedirect?url=%23);Phoenix强类型直接映射Solr类型,并支持分词、Array等复杂类型;自适应回查的优化策略更好解决了数据冗余存储问题。相比于HBase Solr全文检索引擎,大大提高了易用性,并且覆盖绝大部分的场景和需求。但目前SearchIndex还不能完全取代HBase + Solr,对于资深玩家,比较喜欢直接写HBase API和Solr API带来的灵活性,仍然可以选择使用HBase Solr全文检索引擎的方式。

SearchIndex是针对阿里云公共云客户定制开发的一体化云原生在线NoSQL数据库引擎,具有低成本、灵活、易用、稳定等特点,已经被用于物流巴枪、线下支付表单、电商表单、医药实验日志等行业和场景,用户数据量已达数百亿规模,经历过双十一的考验。用户第一步可以只购买HBase实例,全文服务和SQL服务可以后续单独开通,单独升级管理。欢迎感兴趣的开发者共同交流。

 

 

[原文链接](https://yq.aliyun.com/articles/727597?utm_content=g_1000089494)

本文为云栖社区原创内容,未经允许不得转载。
分享到:
评论

相关推荐

    自定义双层嵌套饼图实现

    在IT领域,可视化数据是传达复杂信息的有效方式,饼图作为一种直观的数据表示工具,被广泛应用于各种场景。本文将深入探讨如何实现一个自定义的双层嵌套饼图,其中包括内层饼图、外层饼图的展示,以及动态动画和放大...

    双线性映射需要的库文件

    在PBC库中,可以找到实现不同域参数下的双线性配对函数,例如Weierstrass曲线上的 Tate配对或Ate配对。这些配对函数在密码学应用中至关重要,如身份基加密、可证明安全的签名方案、零知识证明等。 安装和使用这两个...

    利用动态库实现双目标定。

    动态库在软件开发中扮演着关键角色,它们可以封装复杂的算法和功能,便于程序调用。在双目标定中,我们可以创建一个动态链接库(DLL)或共享库(在Unix/Linux系统中),封装双目标定的算法。这样,其他应用程序只需...

    JAVA实现的SSL/TLS双向认证源代码

    3. **服务器端实现**:在`TeslaSSLServer`类中,你需要设置SSLServerSocket,配置它使用之前创建的`SSLContext`。这样,服务器在接收连接时会要求客户端提供有效的证书。 4. **客户端实现**:对应的`TeslaSSLClient...

    python3下的PBC库

    5. **签名与验证**:PBC库还支持基于双线性配对的签名算法,如 Boneh-Boyen 签名方案,可以实现数字签名的生成和验证。 6. **实用工具**:除了核心功能外,PBC库还包含了一些辅助工具,如点的倍乘、点的加法、整数...

    48_你们当时是如何把系统不停机迁移到分库分表的?.zip

    这通常是一个复杂的过程,涉及到数据库架构的调整、数据迁移、双写策略以及回滚计划等关键环节。 描述中给出的链接指向了CSDN(中国软件开发者网络)的一个资源上传页面,可能包含了实现这一目标的具体步骤和技术...

    大数运算库miracl 有了miracl这样的函数库,你可以直接调用函数,来实现你要的公钥密码学的某个功能.zip

    其中,大数运算库如MIRACL(Multiple-precision Integer and Rational Arithmetic Library)为实现复杂的加密算法提供了强大的支持。 MIRACL是一个高效且灵活的大整数运算库,专为处理大整数和复数运算而设计。它...

    基于ORACLE双库结构解决历史数据的查询.pdf

    为了解决这个问题,一种基于ORACLE双库结构的解决方案被提出,旨在有效地管理和查询历史数据,同时保持在用数据库的高效运行。 1. 双库结构概述: 双库结构主要包含两个部分:在用数据库(当前事务数据库)和历史...

    C++函数库查询辞典

    C++语言以其高效、灵活性和强大的功能在软件开发领域占据了重要地位,而其丰富的库函数则是实现复杂功能的关键。 在C++编程中,函数库是必不可少的部分,它为程序员提供了大量预先编写好的函数,可以大大提高开发...

    伪双端口RAM的VHDL实现

    在这个项目中,"nut_tpram"可能是源代码文件或库,用于实现伪双端口RAM的功能。在VHDL程序中,通常会包含实体(Entity)、结构体(Architecture)和配置(Configuration)等部分。实体定义了模块的外部接口,包括...

    c++语言密码学Pbc库,博主亲测有效

    Pbc库提供了在C++中实现双线性对操作的接口,包括生成双线性对、计算双线性映射、执行群运算等。这些功能使得开发者能够方便地构建基于双线性对的密码系统,如身份基加密(IBE)、属性基加密(ABE)、群签名、匿名...

    GDI+双缓存实现简单的图片动画效果

    在Windows编程领域,GDI+(Graphics Device Interface Plus)是一个强大的图形处理库,它扩展了传统的GDI功能,提供了更多的图形绘制和图像处理能力。在本文中,我们将深入探讨如何利用GDI+的双缓存机制来实现一个...

    IEC60870开源实现库

    **IEC60870 开源实现库详解** IEC60870标准是国际电工委员会(International Electrotechnical Commission)制定的一套用于电力系统自动化通信的协议族,它定义了不同设备间数据交换的规则。该标准分为多个部分,...

    sdl任务.rar_双人对战版_用C+SDL库写的俄罗斯方块小游戏

    总的来说,"sdl任务.rar_双人对战版_用C+SDL库写的俄罗斯方块小游戏"是一个很好的学习资源,它将理论知识与实践应用相结合,既展示了C++和SDL库在游戏开发中的应用,又提供了双人对战模式的设计思路。通过深入研究这...

    TIA博途-AT指令实现双字中高低字转换的全局FB库文件-GF-AT-Swap.zip

    总结来说,"TIA博途-AT指令实现双字中高低字转换的全局FB库文件-GF-AT-Swap.zip"是一个方便的工具,它利用AT指令在TIA博途中提供了一个高效的双字拆分和组合功能。通过创建和使用这个全局FB,工程师可以简化代码,...

    基于Solr的多表join查询加速方法

    本文将围绕"基于Solr的多表join查询加速方法"这一主题,深入探讨如何在Solr中实现类似join的功能,并优化查询性能。 在Solr中模拟join操作通常有两种策略:嵌入式数据模型和外部数据源查询(ExternalFileField或...

    智能双电梯的C语言程序实现

    同时,为了实现双电梯的协作,可能还需要引入多线程或并发控制的概念,确保两部电梯的协调运行,避免冲突。 接下来,我们讨论GUI的实现。在C语言中,可以使用如GTK+或Qt这样的库来创建图形界面。这些库提供了丰富的...

    C++实现ini文件读写(Linux和windows平台均可运行)

    通过以上步骤,你可以在C++中实现跨平台的ini文件读写功能,无论是在Windows还是Linux环境下。这不仅锻炼了文件操作和字符串处理技巧,还涉及到平台兼容性的设计,是提升C++编程能力的一个好实践。

    双y轴统计图和条件查询

    在JavaScript中,实现双y轴统计图有多种库可供选择,如D3.js、Chart.js、Highcharts等。这些库提供了丰富的API和配置选项,让我们能够定制出满足需求的图表。 1. D3.js(Data-Driven Documents):这是一个强大的...

    qt制作的视频通话,实现双向视频电话

    【标题】:“Qt制作的视频通话,实现双向视频电话” 在IT行业中,视频通话技术已经广泛应用,无论是个人社交还是企业沟通,它都扮演着至关重要的角色。本项目使用Qt框架来构建一个简单的视频通话工具,这展示了Qt在...

Global site tag (gtag.js) - Google Analytics