Clickhouse运维增强: 存算分离
什么是存算分离
从字面意思理解就是, 存储计算是解耦的, 当需要增加存储资源的时候, 不需要对应的增加计算部分的资源.
Clickhouse的架构是典型的存储计算在一起的方式, 现在我们公司CK的算力紧缺, 存储却相对较低, 可是要扩容的时候, 存储也对应的增加起来, 形成了一定浪费.
存算分离架构的流行主要得益于云服务的兴起, 按需和弹性的资源推向了企业用户, 目前大多数的云上数据库都开始支持存算分离架构.
传统公司的服务器一般采用预算制, 部门一般能申请就会尽量去申请, 高峰时期能有充足的资源预备是他们首要的目标, 低峰期间的资源浪费是可以忍受的.
云上存算分离架构的设计目标有如下几个:
数据一般存储在统一的数据服务中, 且数据服务不绑定单个服务; 典型的做法就是放到S3型存储服务离
计算能够弹性, 扩缩容时间尽量短(某些服务是不支持缩容的);机型大多数要求同构, 少部分支持异构
网络带宽不是首要考虑的点, 云上内网带宽能够足够的大
性能衰减不能太严重, 某些场景需要优于单机水平, 方便对外宣传
上面4个设计点, 1和2比较好解决, 例如Spark + HDFS构成的OLAP服务是一个典型的存算分离架构, Spark和HDFS可以分布在不同的集群上, 计算和存储的扩缩容都可以分开处理.
但第3点在传统公司是难以解决的, 因为机房的带宽非常有限, 一旦跨机房, 性能将直线下降. 所以会将这两个服务部署在一起, 导致部署上依然是存算不分离的.
因此存算分离的一个最大的难点实际上被硬件解决了
所以云服务大多数的设计点在解决第4个问题, 而采用的方案就是缓存.
学过计算机的都知道介质的访问速度:
内存 > SSD > HHD > 远程HDD
在云服务世界里就是:
服务器内存 > 本地高速盘 > 本地普通盘 > S3服务
S3服务作为云服务里面, 最按需, 最弹性, 最Serverless接口的存储服务, 毫无疑问的被大多数服务选中作为最终的数据存储地方.
因此针对S3的访问加速, 也分为前面三种介质模式, 我分别举一个例子来介绍一下.
基于之前的经验, 最新版不一定正确
缓存加速
HDD类型
这种类型比较少见, 因为HDD的性能已经很差了, 相对于S3提升能力不多, 唯一优势是放在同一网络域中, 网络带宽会略会好.
例如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案例
相比于普通磁盘, SSD的性能有成倍的提升, 且成本增加较小.
但SSD也有自身的缺点:
- 相对于普通, 磁盘容量比较小, 磁盘寿命降低
- 相对于内存, 性能查实差了1个数量级
内存加速
内存加速的案例太多了, Redis
和MemCache
就是在业务里经常用到的内存加速.
源码级别也有各种类型的缓存库, 例如guawa
的cache, 具体案例就不介绍了
内存缓存的缺点是:
- 内存相对比较小, 需要小心控制一下内存的换入换出
- 内存相对来说比较昂贵, 只能应用局部数据量的查询
方案比较
缓存方案 | 优点 | 缺点 | 数据量 | 时延 | 适用场景(OLAP) |
---|---|---|---|---|---|
磁盘缓存 | 磁盘容量大 | 性能差 | 10PB | 分钟级 | 离线加速 |
SSD缓存 | 磁盘存储性价比高 | 存储量相对小 | 100TB | <5秒 | 实时查询 |
内存缓存 | 性能快 | 数据易失 成本高 |
<1TB | <1秒 | 数据服务 |
从目前Clickhouse的场景来看, SSD的缓存策略也许更加适合我们的要求.
Clickhouse的存算分离方案
设计要点
首先明确一下设计的指标, 对照着之前的设计要点
设计点 | 说明 |
---|---|
存储 | 存储服务其实就那么几种, 如果在云下, 那么就使用HDFS, 如果在云上就使用S3服务.另外考虑到存储的性能, 可能会购买JuiceFS做存储的性能加速 |
计算 | 不准备支持异构机器, 但集群之间可以异构, 分为存储性和计算型集群; 计算弹性要求扩缩容的能够在5分钟处理完毕 |
网络 | 这个点能做的非常少, 有什么就用什么 |
缓存 | 采用SSD缓存, 将数据文件放置于计算机器的SSD中, 存储只是作为同步方案 |
设计图
跟之前虚拟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操作
节点扩容
依然和虚拟shard的方案很类似, 只是从S3地方完成了拷贝, 具体就不展开了.
方案评价
目前看来这个方案是可行的, 整体对Clickhouse引擎内部的改动也不多, 也决绝了运维最大的难题就是扩容的方案.
但是由于CK的配置和元数据都是单机式的, 更新集群配置需要重启节点, 这就会限制该方案云化的设计.
细节设计还有一定的模糊, 主要是对CK引擎内部还没有那么清晰.
下一步如果能够实现元数据和集群配置的集中化, 那么对自动化会有很大的优势.