Clickhouse运维增强: 存算分离

什么是存算分离

从字面意思理解就是, 存储计算是解耦的, 当需要增加存储资源的时候, 不需要对应的增加计算部分的资源.

Clickhouse的架构是典型的存储计算在一起的方式, 现在我们公司CK的算力紧缺, 存储却相对较低, 可是要扩容的时候, 存储也对应的增加起来, 形成了一定浪费.

存算分离架构的流行主要得益于云服务的兴起, 按需和弹性的资源推向了企业用户, 目前大多数的云上数据库都开始支持存算分离架构.

传统公司的服务器一般采用预算制, 部门一般能申请就会尽量去申请, 高峰时期能有充足的资源预备是他们首要的目标, 低峰期间的资源浪费是可以忍受的.

云上存算分离架构的设计目标有如下几个:

  1. 数据一般存储在统一的数据服务中, 且数据服务不绑定单个服务; 典型的做法就是放到S3型存储服务离

  2. 计算能够弹性, 扩缩容时间尽量短(某些服务是不支持缩容的);机型大多数要求同构, 少部分支持异构

  3. 网络带宽不是首要考虑的点, 云上内网带宽能够足够的大

  4. 性能衰减不能太严重, 某些场景需要优于单机水平, 方便对外宣传

上面4个设计点, 1和2比较好解决, 例如Spark + HDFS构成的OLAP服务是一个典型的存算分离架构, Spark和HDFS可以分布在不同的集群上, 计算和存储的扩缩容都可以分开处理.

但第3点在传统公司是难以解决的, 因为机房的带宽非常有限, 一旦跨机房, 性能将直线下降. 所以会将这两个服务部署在一起, 导致部署上依然是存算不分离的.

因此存算分离的一个最大的难点实际上被硬件解决

所以云服务大多数的设计点在解决第4个问题, 而采用的方案就是缓存.

学过计算机的都知道介质的访问速度:

内存 > SSD > HHD > 远程HDD

在云服务世界里就是:

服务器内存 > 本地高速盘 > 本地普通盘 > S3服务

S3服务作为云服务里面, 最按需, 最弹性, 最Serverless接口的存储服务, 毫无疑问的被大多数服务选中作为最终的数据存储地方.

因此针对S3的访问加速, 也分为前面三种介质模式, 我分别举一个例子来介绍一下.

基于之前的经验, 最新版不一定正确

缓存加速

HDD类型

这种类型比较少见, 因为HDD的性能已经很差了, 相对于S3提升能力不多, 唯一优势是放在同一网络域中, 网络带宽会略会好.

img

例如MRS服务, 就是云上的HDFS+Spark/Hive这套大数据组件, 用户结构数据有一些部分会上传到S3上, 这时使用Spark直接分析OBS数据的性能会非常差, 这时MRS服务做了一个数据导入的功能, 将S3的数据导入到MRS集群的HDFS上, 这样用Spark查询时,性能会提升一部分. 但是由于HDD糟糕的性能, 提升效果有限, 因此会加入CarbonData等有索引的数据结构查询.

另外随着S3Query的能力开放, 直接在S3上查询的能力也开始发力, 后续通过HDD的加速大概率会消失.

云上的HDFS最多是为了兼容企业的老接口, 一旦S3能全面兼容HDFS, MRS这种内建HDFS的方案将被取消.

目前看到快手是直接用基于HDD的HDFS做存算分离方案

SSD加速

SSD是一种永久性的存储介质, 不会丢失数据, 因此经常会用到实时场景做缓存.

美团就有使用SSD加速Kafka案例

img

相比于普通磁盘, SSD的性能有成倍的提升, 且成本增加较小.

但SSD也有自身的缺点:

  • 相对于普通, 磁盘容量比较小, 磁盘寿命降低
  • 相对于内存, 性能查实差了1个数量级

内存加速

内存加速的案例太多了, RedisMemCache就是在业务里经常用到的内存加速.

源码级别也有各种类型的缓存库, 例如guawa的cache, 具体案例就不介绍了

内存缓存的缺点是:

  • 内存相对比较小, 需要小心控制一下内存的换入换出
  • 内存相对来说比较昂贵, 只能应用局部数据量的查询

方案比较

缓存方案 优点 缺点 数据量 时延 适用场景(OLAP)
磁盘缓存 磁盘容量大 性能差 10PB 分钟级 离线加速
SSD缓存 磁盘存储性价比高 存储量相对小 100TB <5秒 实时查询
内存缓存 性能快 数据易失
成本高
<1TB <1秒 数据服务

从目前Clickhouse的场景来看, SSD的缓存策略也许更加适合我们的要求.

Clickhouse的存算分离方案

设计要点

首先明确一下设计的指标, 对照着之前的设计要点

设计点 说明
存储 存储服务其实就那么几种, 如果在云下, 那么就使用HDFS, 如果在云上就使用S3服务.另外考虑到存储的性能, 可能会购买JuiceFS做存储的性能加速
计算 不准备支持异构机器, 但集群之间可以异构, 分为存储性和计算型集群; 计算弹性要求扩缩容的能够在5分钟处理完毕
网络 这个点能做的非常少, 有什么就用什么
缓存 采用SSD缓存, 将数据文件放置于计算机器的SSD中, 存储只是作为同步方案

设计图

image-20210715142722756

跟之前虚拟id的方式基本上一致, 但存储会统一放入S3中, 机器上会有一个同步备份, 另外会有一个manager管理这些数据, S3和HDFS更像一个数据备份和快速恢复的地方.

之前Manager是游离整体架构之外的辅助角色, 现在是强相关组件, 因此写入了架构图

  • 数据写入
    • 实时数据, 会写入Clickhouse节点, 数据同MergeTree引擎同步到S3上
    • 离线数据, 会直写拷贝到S3上, 由Manager将数据块Attach对对应的数据节点
  • 数据读取

    • 读取CK节点上, 缓存的数据, 数据以CK上的为准
    • CK依然有副本节点, 用于加数读取
  • 数据变更

    • 由CK节点处理请求, 并CK管理HDFS上的DP
  • 数据管理

    • 小文件问题: HDFS上的一个DP文件夹会序列化为单个文件, 数据上传时序列化, 数据下载(attach时)反序列化为文件夹
    • 元数据: 目前还不打算弄成统一的元数据系统, 由manager来管理员数据, 扩容机器的时候, manager先初始化所有的表, 那么这个时候, 就要禁止用户DDL操作

节点扩容

image-20210715144933939

依然和虚拟shard的方案很类似, 只是从S3地方完成了拷贝, 具体就不展开了.

方案评价

目前看来这个方案是可行的, 整体对Clickhouse引擎内部的改动也不多, 也决绝了运维最大的难题就是扩容的方案.

但是由于CK的配置和元数据都是单机式的, 更新集群配置需要重启节点, 这就会限制该方案云化的设计.

细节设计还有一定的模糊, 主要是对CK引擎内部还没有那么清晰.

下一步如果能够实现元数据和集群配置的集中化, 那么对自动化会有很大的优势.