共计 4713 个字符,预计需要花费 12 分钟才能阅读完成。
本篇文章整顿自知乎在线基础架构负责人白瑜庆在 PingCAP Infra Meetup 上的演讲实录。 本文讲述了知乎与 TiDB 的渊源,介绍了一款基于 TiDB 生态研发的开源产品 Zetta,可能在躲避 HBase 性能问题同时,减小 TiDB 部署后分布式架构下的零碎提早。
背景详情
BigTable 数据模型
在开始介绍 Zetta 之前,咱们先来看看 BigTable。BigTable 是一个稠密的多维度的有序的表(Sparse multidimensional sorted map),它是谷歌开发的用来解决数据量宏大的场景下的数据索引问题的数据模型。谷歌爬虫的数据量十分大,BigTable 不仅能提供满足其业务场景的低延时存储服务,同时,在开发效率上,还提供了宽列能力,即数据结构化,对于开发非常敌对。目前,BigTable 被利用于 Google Earth、Google Analytics、Personalized Search 等须要进行数据分析的场景。
知乎面临的挑战
当知乎倒退到 2016、2017 年的时候,随着业务增长,遇到了很多和 Google 相似的问题。在数据规模持续增长的环境下,很多的场景其实出现的是 NoSQL 的场景,它并不是一个十分严格的关系型的场景。
举个例子,知乎的 Redis 当初曾经有了三万到四万左右个实例。如果对它们做微服务化革新,服务之间的调用会十分频繁。而对于某些在线服务,它要求低提早,高吞吐,高并发。
比方首页已读的服务,须要在首页展现时过滤掉用户已读的数据。每次知乎展现的首页的数据是用户维度加上内容维度的一个十分大的数据集。这其中还包含 AI 用户画像服务,用户画像是一个十分稠密的数据,它贮存了用户对哪些内容感兴趣的一个十分稠密的表。这些场景一直对咱们的基础设施产生冲击。
引入 HBase
在那个期间知乎最终抉择了 HBase。HBase 是一个优良的 BigTable 的开源实现,它有很成熟的生态。然而同时它也有一些小问题,如不反对跨行事务、二级索引不欠缺等。
只管能够利用第三方的组件来解决(比方 Phoenix),但同时也会产生新的问题:零碎组件十分多,保护起来很简单。知乎在应用过程中也遇到了一些问题。
- 第一,HBase 的应用老本十分的高 。要让 HBase 变得好用,须要投入十分业余的工程师团队来调试,这些工程师不仅须要具备相干的常识,还要对 HBase 特地理解。
- 第二, 业务接入 HBase 的老本很高 。很多时候咱们是应用 MySQL 或者 NoSQL 进行开发,所以迁徙到 HBase 咱们须要付出比拟大的工作量。
- 第三,HBase 的调优难度很高 。举个例子,HBase 的 Cache 和 HDFS 的一些参数调优,须要十分粗疏地针对业务场景进行调整,难度高。
总结起来,HBase 并不是知乎在以后业务场景下的最优解。事实上,即便知乎团队在十分致力的调优、优化的状况下,HBase 的响应工夫依然始终在激烈稳定。而知乎团队不仅心愿响应工夫尽可能低,还心愿它可能稳固,这一点 HBase 满足不了。
自建 RBase
基于上述情况,在 2017 年前后,知乎利用 K8s、Kafka、Redis、MySQL 等成熟组件研发出了 RBase。RBase 下层是 HBase,底层存储是 MySQL。MySQL 部署在 K8s 上,两头接入 Kafka,而后利用 Cache Through 的形式最大化升高提早。
然而 RBase 也存在一些问题。在中等数据规模的场景下,MySQL 每次进行 Sharding 以进行集群裁减都十分麻烦。并且因为数据库里的数据是无序的,所以无奈比较顺利的进行数据分析。在这种状况下知乎仍然开发出了首页已读过滤和反作弊设施指纹性能,并且一直进行迭代。
到 2019 年,知乎的数据量进一步增长,到最初 MySQL 的 Sharding 曾经成为这个零碎压力最大的中央。所以,RBase 进一步降级,引入了 TiDB 来替换 MySQL。
整体来说 RBase 还是这套架构,然而 MySQL Sharding 的问题彻底解决了,同时这个零碎还保障了不错的性能,可能承载更多的服务。然而这又带来一个新的问题:分布式数据库不可避免的会减少零碎的提早。
为了更好的解决上述问题,最初,Zetta 诞生了。
Zetta 的诞生
数据库的三种典型场景:Transactional / Serving / Analytical
在数据库里有三种场景,其中有两种是大家比拟相熟的, 事务和剖析 。事务场景包含金融交易等简单业务逻辑、强关系模型的场景。剖析场景包含像 Adhoc、ETL、报表等场景。然而还有一种场景:Serving 的场景 ,它用于在线的服务,不存在强关系。
用户画像服务就是 Serving 的一种场景,它可能带有稠密的宽列,还有实时计算等。而 Zetta 正是在知乎 Serving 场景需要一直增长的背景下诞生的。
Zetta 架构解析
技术倒退的最终目标都要服务于价值,老本驱动技术提高。
事务的数据价值很高,大数据的数据价值密度绝对较低,而 Serving 是基于两头的一个场景。Zetta 就是在这个价值密度条件下升高查问老本和应用老本的一个老本折中的产品。
知乎的 Zetta 心愿成为 TiDB 生态搭档,因为 TiDB 的生态,不仅是凋谢的,而且是成熟的。同时,Zetta 也心愿能够在 TiDB 的生态外面成为 Serving 场景下的搭档。
在此之前,咱们也有一些衡量,如下图,彩色局部是咱们曾经做了,橙色是咱们正要做的,蓝色是咱们当初打算去做的。
Zetta 能够抉择一致性的级别,反对在强统一读和弱统一读的抉择,当然这是依据业务场景来决定的。Zetta 还反对非事务,比如说它能够为了更极其的性能而放弃对事务的要求。另外,Zetta 在将来将会反对缓存读取,这将带来性能的进一步晋升。
在拜访模式中,Zetta 反对宽列的模式。宽列就是一个特地宽的表,这个列是能够一直动静减少的,并且还能够抉择高表模式或者宽表模式,这两种模式在物理上是不太一样的,然而在 Zetta 中能够设置。另外 Zetta 还应用了聚簇索引以晋升性能,此外还有 Hash 打散。
🌟 其余能力
Zetta 还提供了二级索引的能力,同时 Zetta 也不须要多版本,因为多版本有的时候对于开发的同学来说并不重要,所以 Zetta 开发团队在理论场景中把多版本的概念弱化了。同时 Zetta 反对多种协定 ,它不仅自身是能够用 HBase Thrift Server 的形式,也反对 MySQL 和 HBase 原生的形式。
除此之外,Zetta 还与 Flink 买通,使 Zetta 能够作为大数据 Connector。接下来知乎团队还会持续开发数据 TTL。在大数据场景下,数据的 TTL 是十分理论的需要,因为数据十分的多,所以无用的数据须要定期进行清理。
另外,Zetta 还反对全文检索,并且反对 Redis 协定的接入 。
🌟 架构概览
上面是 Zetta 的架构图。第一个外围是 TableStore 的 server,它的底层存储是 TiKV,然而知乎团队从新设计了数据的构造,包含表映射 KV 的办法等等。
重点说一下接入层,接入层自身是没有状态的,为了晋升易用性,Zetta 和下层接入层是通过 grpc 进行通信的。然而对于用户来说,裸露 grpc 接口也不好,下层的数据对用户来说不够敌对。易用性是通过 MySQL 或者 HBase 的形式将数据映射到 Zetta 下面去,同时也反对数据模型。
为了做到低提早,Zetta 实现了一个缓存层,用户写的时候通过 Cache Server 去做缓存,相当于间接写到 Zetta,而后再更新到 KV。数据的读和写都产生在 Proxy 层和 cache 层,然而它们会依据申请做缓存和路由。Zetta 提供了一个残缺的解决方案,供开发人员去决定应用哪种形式接入 。
Zetta 在知乎的利用
⽣产环境应⽤的收益
Zetta 的投入使用后, 给服务的应用方和提供方都带来了十分大的收益。
应用方失去了十分大的性能晋升。不仅服务的提早降落了,响应的工夫稳固了,并且实现了升高服务老本和物理老本的指标。
而对于服务的提供方来说, 不再须要去思考其余的组件,只须要保护好 Zetta 和 TiKV 集群,极大升高了保护的老本 ,同时所需资源老本也大幅升高。除此之外,因为 TiKV 社区十分沉闷,开发人员在遇到问题时能够第一工夫进行反馈,并且社区会进行修复,始终继续地改良 TiKV。这样 Zetta 便与 TiDB 生态产生了良性的互动,继续地进行基础设施的迭代,相互受害。
具体的状况能够通过一些图表和数据来展现。
⽣产环境应⽤
🌟 已读服务 & 已推服务
在生产环境的利用中,知乎的已读服务,在应用 Zetta 后,提早从 100ms 降落到 90ms,存储容量也大幅度降低了。已推服务在应用 Zetta 后,也是实现了响应工夫和存储量的大幅降落。
🌟 搜寻高亮数据
知乎搜寻框的搜寻高亮数据的服务,它原本是应用一个名叫 Ignite 的分布式数据库,在应用 Zetta 代替后,提早的工夫大幅升高。同时,除了性能的晋升外,运维的难度升高了,再也不须要有专门的运维人员去治理 Ignite 数据库了。
🌟 图片元数据服务
还有一个是 Zetta 在图片元数据服务中的利用。这个图片的意思是,通过实现 HBase 到 Zetta 的切换,实现了提早和存储的大幅升高。其实代码上并没有扭转,只是间接把 Thrift server 的地址从 HBase Thrift server 改为 Zetta Thrift server。
可能大家会有疑难, 为什么在切换到 Zetta 后服务的提早和存储需要会降那么多?
- 第一个起因,咱们调整 HBase 参数的能力比拟无限,知乎 HBase 底层的存储没有压缩。
- 第二个起因,HBase 有很多版本。如果在线上开 Compression,资源耗费是十分可怕的,且其影响是不可控的,所以知乎很少开 Compression。只有在业务低峰的时候,才敢去尝试开一次。
当然,咱们被问到最多的问题是说知乎 HBase 的 Compression 须要多长时间。这个其实也不确定,个别是在中午一点到第二天晚上七点之间能够实现。
🌟 创作者核心
另外,创造者核心服务也利用了 Zetta。创作者核心是一个展现创作者数据的服务。原来创作者核心的外围数据全副都在 HBase 上,当初通过迁徙,数据从原来 HBase 外面 NoSQL 表,实现了从 HBase client 切到 MySQL client 的扭转。
当初,查问的代码能够写的十分分明,每次查问就是一个 SQL。而在 HBase 外面,这个表非常复杂。所以这样带来两个益处,首先是性能上有所晋升,其次也代码更加清晰明了。切换后,服务的提早升高了,同时也打消了提早的抖动。
生产环境规划接入服务
下一步,知乎打算把 Zetta 推广到知乎的其余服务上。服务等级分为从高到低的 S、A、B 三层。S 可能波及到的 HBase 集群数可能有 4,接入形式有 ThriftServer 或者原生的形式,数据量可能有 120TB。预计当这个服务切换为 Zetta 的时候,存储容量将会有比拟大的降落。
Zetta 的将来
将来, 知乎会对 Zetta 做进一步的晋升 。
- 第一个是让 Zetta 自身的性能晋升,另外是性能上的晋升。
- 第二个是知乎会拓展更多的利用,推广 Zetta 在知乎的场景,同时可能造成一些最佳实际。
- 第三个是要去拓展场景。咱们当初可能专一于在线上做一些事件,前面会缓缓去找到适宜大数据的场景的应用案例作为最佳实际。
- 最初,Zetta 心愿在将来能够与 TiDB 进行整合,心愿 Zetta 可能成为 TiDB 的生态搭档。
Zetta 在 GitHub 的我的项目地址是:https://github.com/zhihu/zetta,当初最新的代码是在知乎外部的仓库,大家如果对这个我的项目感兴趣、想交换的,也能够在我的项目外面分割咱们,或者有场景想要接入 Zetta,咱们也很乐意帮忙大家。