Contents
原文:Building ClickHouse Cloud From Scratch in a Year
译者注
ClickHouse团队这篇文章自今年3月发布以来,就看到Twitter上有很多人转发或推荐了这篇文章。
这是一篇教科书级别的文章,讲述如何基于Kubernetes构建一个Serverless云服务。因为我从事的领域和这方面相关,并且我所参与的产品开发与这篇文章有很多相关之处。我研读了这篇文章很多很多遍,然后决定翻译这篇文章翻译,其中添加了一些我的注解。
前言
你有好奇过在一年内开发一个无服务器(Serverless)的SaaS服务都需要些什么吗?在这篇博文中,我们将介绍我们如何从零开始构建ClickHouse Cloud ——一个基于全世界最流行的OLAP(online analytical processing)数据库之一构建的托管服务。我们深入研究了我们的规划流程、设计和架构决策、安全性和合规性考虑因素,如何在云上实现全球可扩展性和可靠性,以及我们在此过程中学到的一些经验教训。
最新消息和采访
鉴于这篇文章的受欢迎程度,我们决定借此机会回答视频中出现的一些问题。
Scarlett:
如果你不方便访问YouTube,请使用这个链接。下面是对视频内容的简短总结。建议看完全文后再回来阅读这一部分。
设定优先级和路线图(Roadmap)
- 基于时间点的路线图:提前设定好在那个时间点要交付哪些东西。
- 和数百位用户交谈,了解用户想要什么。
- 使用类似栈的思想排列用户的需求:这为用户的需求设定了优先级。
- 持续地重新评估:一些功能比预计的更重;一些功能存在未预料到的依赖。
- 平衡功能性需求和非功能性需求:不为了功能交付而牺牲质量和稳定性。
最难的事情是什么?
- 招聘和组建团队。
- 在截止日期前交付(meet deadline)。
- 一些需求很难估计和规划
- 一些需求可以被缩减(down-scope),但有些只能要么交付要么推迟或砍掉。
- 例如备份功能实现起来比预计困难很多,因此团队决定将其从内部预览版中移除,推迟到公开预览版才交付。
团队的大小和结构
- ClickHouse是一个全球分布,远程工作的团队。
- 雇佣最好的人,维持较为扁平的结构。
- 每个工程师关注一个细分领域,如安全,可靠性或可观测性,并相对独立地工作。
- 团队之间(工程,产品,销售)紧密地合作。
定价
- 使用现用现付(Pay as you go)模型,使用客户能够理解的维度来计费。
- 团队做出了几种方案,并在私有预览版中测试,即使没有真正向用户收费。
- 参与私有预览版的客户可能存在选择偏差(Selection bias):参加私有预览版的客户通常更熟悉产品,相同的问题到了公开预览阶段,因为参与的客户群体不同,可能得出完全不同的结论。
- 如果某样东西让客户感到困惑,就应该像对待bug一样对待这个问题。
未来的展望
- 支持更多云服务商
- 探索更多用例
时间线和里程碑(Milestone)
我们的时间表和计划可能有些不寻常。自2016年以来,ClickHouse一直是一个非常受欢迎的开源项目,因此当我们在2021年成立公司时,有大量的积压已久的需求等待我们去实现。因此,我们设定了一个激进的目标,即在一年内快速地构建ClickHouse Cloud产品。
我们提前确定了里程碑——5月发布内部预览版、10月发布公开测试版、12月发布正式版。然后思考在每个日期之前交付哪些功能是可行的,以及需要哪些资源来实现。我们需要谨慎地确定每个里程碑的优先级,并考虑哪些项目可以同步进行。我们在构建云产品、市场分析以及与早期潜在客户就其痛点进行对话中获得了经验,我们通过这些经验来设定功能的优先级。
我们总是计划在每个里程碑中做更多事情,然后重新评估我们完成了哪些事情并调整了目标和scope。有时我们出乎意料地超额完成了任务,例如,在短短几周内构建了一个功能齐全的控制平面(Control Plane) 最小可用产品(MVP),而其他时候,纸面上看起来简单的事情实际上需要更长的时间,例如,备份在巨大的数据量下变得很困难。每个版本中,我们使用类似栈的思想来按照优先级管理每个版本的功能,并明确标记了blocker(会阻断项目进程的关键需求),重要功能和可有可无的功能。当我们不得不削减功能时,我们能够毫不犹豫地放弃最底层的功能。
我们不想闭门造车,因此我们邀请了对云服务感兴趣的ClickHouse用户在产品早期就开始试用。我们邀请了50名潜在客户,从5月到7月进行了漫长的内部预览。我们并没有向这些用户收费,因为我们的目标是从真实世界中的需求学习,获得反馈,并和客户一起成长。
从一开始,我们就将易用性放在首位。我们专注于使onboard流程尽可能顺畅。我们使用系统生成的邀请、自助onboard和自动化的客户支持流程。同时,我们确保为每个内部预览用户提供一个单独的Slack频道,这样我们就可以与客户直接沟通并迅速有效地解决问题。
ClickHouse Cloud的架构
我们的目标是构建一个任何开发人员或工程师在无需深入了解数据仓库,也不需要明确定义尺寸和管理基础设施的情况下就可以立即开始使用的云产品。
Scarlett: 从我个人的经验来看,定义尺寸(sizing)是一个对于客户和服务商来说都比预想中更有挑战的工作。一方面,客户往往并不清楚他们需要多大的实例,比如客户手里有1TB的数据需要分析,而他们并不知道分析这些数据需要多少CPU核心或多大内存,这需要客户和销售部门共同的努力来得出这个问题的答案;另一方面,客户很可能会低估数据的增长速度,所以他们可能会比预计更快地遇到需要扩容计算/存储资源的问题。
我们选择了“共享一切”且存算分离的架构。这意味着存储和计算是解耦的,可以单独扩展。我们使用对象存储(例如 Amazon S3)作为分析数据的主存储,使用本地磁盘仅用于缓存、元数据和临时存储。
这是“共享一切”架构的结构图。
我们选择此架构的原因是:
- 这极大地简化了数据的管理:无需为集群和存储提前设定尺寸,无需物理上为数据分片,在集群扩容或缩容时无需再平衡数据,不会再因为固定的计算或存储容量而导致计算资源的闲置。
- 基于我们的性能测试和运行真实世界中的工作负载的经验,我们发现这种架构可以实现对于分析工作的最佳的性价比。
选择这一路径而产生的额外工作包括:
- 对象存储和本地硬盘相比有更高的延迟,因此我们需要在对象存储的基础上实现智能缓存、并行访问和预存取(Prefetch),以确保分析查询速度。
- 对象存储访问,尤其是写入,的成本很高,因此我们必须仔细研究写入的文件数量、频率以及如何优化该成本。 事实证明,这些努力还帮助我们提高了整体可靠性和性能。
Scarlett: 这篇文章讲解了使用对象存储作为主要存储的好处:S3 as the universal infrastructure backend | by Davis Treybig | Innovation Endeavors | Oct, 2023 | Medium
ClickHouse Cloud的组件
ClickHouse Cloud 由两个独立的逻辑单元组成:
- 控制平面(Control Plane) – 这是面向用户的部分:UI和API使用户能够操作ClickHouse Cloud,授予对其ClickHouse服务的访问权限,并与数据进行交互。
- 数据平面(Data Plane) – 这是面向基础设施的部分:管理和编排物理ClickHouse集群的功能,包括资源分配、配置、更新、扩展、负载平衡、隔离不同租户(tenant)的服务、备份和恢复、可观测性(observability)、计量(metering)(收集使用数据)。
下面的架构图展示了ClickHouse Cloud的组件及其交互。
一个双向的API层是控制平面和数据平面的唯一集成点。出于以下几种原因,我们决定使用REST API来实现:
- REST API独立于用于实现它的具体技术,这能够帮助我们避免控制平面和数据平面产生的依赖。我们可以将数据平面从Python改为Golang编写而无需对控制平面做任何改动。
- 这带来了很大的灵活性,将若干服务组件解耦可以使它们各自独立地迭代。
- 因为请求是无状态的,所以各个组件可以高效地扩容。
当客户端执行一个需要与数据平面交互的动作时,例如创建一个新的集群或获取当前集群的状态。控制平面将发送一个请求到数据平面。需要从数据平面传回到控制平面的事件,例如一个集群被成功创建,监控数据事件,警报等,会使用消息中间件(SQS,Google Pub/Sub)传递。
Scarlett:
这是我个人非常感兴趣的一部分。也是我过去一段时间在做的事情之一。
一个常见的问题就是数据平面通常位于一个私有网络内,只通过Load Balancer来暴露服务,并通过NAT Gateway来提供上行(Outbound)通信(类似于这篇文章中提到的架构)。那么控制平面向数据平面的通信就成为了一个问题。
通常来说这个问题要么从网络层面解决(VPN,Transit Gateway),要么从应用层面解决,比如gRPC,SQS。我个人很喜欢REST API这个设计,很好地平衡了安全,性能需求和工程复杂度。如果使用API Gateway或Load Balancer暴露API,配合mTLS或第三方服务(如Auth0)提供的Machine-to-machine认证服务可以进一步确保安全,并降低实现起来的复杂度。
这些API的实现位于数据平面的不同组件中。这一部分对用户是透明的,因此我们有一个“数据平面API门面”。数据平面API完成的一些任务包括:
- 开始/停止/暂停ClickHouse服务
- 修改ClickHouse服务配置
- 终结点(Endpoint)的暴露方式(例如HTTP, GRPC)
- 终结点配置(例如FQDN)
- 终结点的安全配置(例如private endpoints, IP filtering)
- 创建用户数据库的主账号及重置密码
- 获取关于ClickHouse服务的信息
- 关于终结点的信息(例如FQDN,端口)
- 关于VPC Peering的信息
- 获取ClickHouse服务的状态信息
- 正在创建,就绪,正在运行,暂停,降级模式(Degraded)
- 订阅状态改变的事件
- 备份和恢复
多平台云(Multi-Cloud)
我们的控制平面运行在AWS上,但是我们的目标是将数据平面部署在包括GCP和Azure在内的所有主流云服务商上。数据平面应封装针对各个云服务商的具体逻辑,因此控制平面不需要考虑这些细节问题。
我们最初在AWS上发布了正式版,但同时在Google云平台 (GCP) 上开始了概念验证工作,以确保和云服务商有关的挑战被尽早发现。 和预期中一样,我们需要找到AWS服务的替代品,但这项工作总体来说是增量的。 我们主要关心的是S3之上的计算和存储分离需要多少工作才能移植到另一个云提供商。 令我们欣慰的是,在GCP中,得益于Google Cloud Storage (GCS) 的S3 API兼容性,除了身份验证方面的一些差异之外,我们对S3的对象存储支持基本上可以不做任何改动就可以直接工作。
Scarlett: Multi Cloud一直是SaaS的挑战之一。对于三大主流云服务商而言,他们提供的产品几乎一致,但是又有很多细节上的不同。比如Azure Blob不是S3 Compatible;GCP的VPC是Global;GCP的File Store需要一些额外字段等等。这使实现Multi-cloud看起来很简单,但做起来就会遇到各种各样的问题。
设计决策
在这一章节我们会回顾我们作出的设计决策以及这些决策背后的原因。
Kubernetes vs 虚拟机
我们决定使用Kubernetes作为计算基础设施,因为其内置的扩容/缩容,调度,监控和内置的服务发现,以及简易的和负载均衡器的集成。Opertor模式使得集群内部发生的一切可以被自动化。同时更新,包括应用和操作系统更新都变得更容易,并且100%云无关(cloud agnostic)。
Scarlett: 近几年很多大公司都苦于Cloud vendor lock in的问题,于是云无关(cloud agnostic)的概念应运而生。Kubernetes相当于将云服务商的IaaS做了一层进一步的抽象,而这一层抽象适用于各个公有云平台,甚至混合云和On-prem。
kOps vs 托管的Kubernetes
我们使用EKS——AWS的托管Kubernetes服务(以及其他云服务商的相似服务),因为这帮我们从管理Kubernetes集群的负担中解脱出来。我们考虑过kOps,一个流行的可用于生产环境的Kubernetes管理软件,但是我们认为作为一个小型团队,使用全托管的Kubernetes服务能够帮助我们更快地到达市场。
网络隔离
我们使用Cilium因为它使用eBPF并且提供高吞吐量,低延迟和较低的资源消耗,尤其是当服务的数量较大时。并且它可以在三大主流云服务商上工作,这是我们做决策时非常注重的一点。我们考虑过Calico,但是它是基于iptables而不是eBPF,并且无法达到我们的性能要求。这是一篇来自Cilium团队的博客,文章讲解了其中的一些技术细节以及基准测试,这些内容帮助我们理解了其中的细微差别以及trade-offs。
Scarlett: 截至2023年,AWS自带的VPC CNI Plugin应该已经支持了Kubernetes network policy来实现网络隔离。
数据平面API服务: Lambda vs Kubernetes
当我们开始构建ClickHouse Cloud时,我们使用AWS Lambda构建了数据平面的API层,因为Lambda可以使我们在非常快的时间内完成开发。我们使用了serverless.com框架。当我们开始准备Beta和正式版发布时,我们更清晰地意识到迁移到在Kubernetes上运行的Golang程序能够帮助我们降低代码部署的时间并通过使用ArgoCD和Kubernetes优化部署流程。
负载均衡器 – AWS NLB vs Istio
对于内部预览,我们为每个服务配置了一个AWS网络层负载均衡器(NLB)。因为AWS对于每个账号的NLB数量有限制,我们决定使用Istio和Envoy作为共享的ingress proxy。Envoy是一个通用的L4/L7反向代理,并且可以轻松地扩展,为特殊协议,如MySQL,Postgres等,提供丰富的功能。Istio是最流行的Envoy控制平面实现,这两个项目都已经开源超过5年,已经足够成熟并且广泛地在工业界被采用。
Istio使用server name indicator (SNI)来将流量路由到不同的服务。我们使用cert-manager和Let’s Encrypt来签发公共证书,并且使用单独的Kubernetes集群来运行代理以确保我们可以扩容集群来为增加的流量提供服务,并减少安全问题。
Scarlett:
Envoy可以算是业界通用的标准了,是很多大/中/小厂采用的方案。更轻量化的类似方案有Traefik和Nginx Ingress。这些常见方案都有其对应的Ingress Controller实现,后期切换起来也相对容易。
Confluent Istio Whitepaper: 20210414-WP-Confluent_and_Istio_Service_Mesh
消息代理和异步通信
我们将SQS用于数据平面内部的通信以及控制平面和数据平面之间的通信。虽然这不够“云无关”,它很容易使用且价格低廉。使用SQS缩短了我们的上市时间,并且减少了管理这部分基础设施的工作量。迁移到其他云服务,如Google Pub/Sub,所带来的工作量也是极小的。
使用对象存储作为主要存储
如前文所述,我们使用对象存储(如 AWS的S3或GCP的GCS)作为主要数据存储,并使用本地固态硬盘储存缓存和元数据。对象存储具有无限可扩展性、持久性,而且在存储大量数据时成本效益更高。在对象存储上规划数据存储时,我们最初为每个逻辑ClickHouse服务使用单独的S3存储桶,但很快就达到了AWS的限制。因此,我们转而共享存储桶,不同的服务使用桶中的不同的子路径,并通过维护独立的IAM Role/service account来保证数据安全。
认证与凭据
我们很早就决定不在我们自己的服务中存储控制平面或数据库凭据(credentials)。我们使用Amazon Cognito进行客户身份和访问管理(CIAM),当你创建控制平面账户时,凭据就保存在Cognito中。当用户创建一个新的ClickHouse服务时,需要在onboard过程中保存凭据,凭据在会话结束后就不再被保存。
Scarlett: 可能大部分人都没有接触过Cognito,大家更熟悉的Auth0是一个类似的服务。
可扩展性和可用性
可扩展性
我们希望我们的产品能够无缝扩展,以在不影响服务性能的情况下应对用户流量的增长。Kubernetes允许我们轻松扩展计算资源,通过自动故障转移和自我修复确保应用程序的高可用性,实现可移植性,并提供与存储和网络等其他云服务的轻松集成。
弹性伸缩(Auto-Scaling)
通过自动扩容/缩容支持不同的工作负载模式是我们的一个重要目标。由于存储和计算是分开的,我们可以根据每个工作负载的利用率来增加或减少CPU和内存资源。
弹性伸缩系统由两个部分组成:idler和scaler。idler的职责是暂停当前没有访问流量的Pod。scaler负责确保服务有足够的资源(在一定范围内)来高效地响应当前的查询组合和查询率。
ClickHouse的idle设计是一种基于Knative的激活器(activator)模式的定制化实现。由于我们的代理(Envoy)与Kubernetes Operator紧密集成,因此我们可以省去Knative中所需的一些组件。
Idler会监控各种服务参数,以确定Pod的大致启动时间。根据这些参数,它会计算出一个空闲期(idling period),在这段空闲期内,如果没有收到请求,则该Pod会被取消分配(de-allocate)。
ClickHouse自动缩放器与Kubernetes生态系统中的自动缩放组件(如垂直和水平自动缩放器)非常相似。它与这些现成系统的区别主要体现在两个方面。首先,它与我们的云生态系统紧密集成。因此,它能够使用来自操作系统、ClickHouse服务器的指标,以及来自查询使用情况的一些信息来确定应为服务分配多少计算资源。其次,它对运行有状态服务所需的Disruption Budget有更强的控制。
Scarlett: 业界常见的Kubernetes Auto scaling工具有Knative和Keda。这里相当于是Auto scaling的一种特殊场景——Scale到0,这个问题本身Knative和Keda已经提供了成熟的工业级解决方案,但具体怎么实现还需要看operator和应用的设计。
每隔 30 分钟,它就会根据这些信息的历史和当前值计算服务应分配的资源量。它使用这些数据来确定是否应增加或缩减服务资源。自动缩放器会根据启动时间和使用模式等因素确定进行更改的最佳时间。我们将继续不断改进,通过纳入更多输入和进行更复杂的预测,使这些建议更快更好。
可靠性
数据对企业至关重要,在当今时代,没有人能够容忍基础设施服务出现停机。我们很早就知道,ClickHouse Cloud需要具有高可用性,能够从内部故障中快速恢复,并确保不会影响系统的整体可用性。集群拓扑结构的配置是这样的:生产服务的Pod分布在3个可用区(AZ)上,开发服务的Pod分布在2个可用区(AZ)上,这样集群就能从区域故障中恢复。我们还支持多个区域,因此一个区域的故障不会影响其他区域的服务。
为了避免在一个云账户中遇到资源限制,我们的数据平面采用了蜂窝架构(cellular architecture)。”单元”是独立自主的单元,彼此独立运行,为整体服务提供高度的容错性和弹性。这有助于我们根据需要启动更多的数据平面单元,以满足增加的流量和需求,并在必要时隔离不同的服务。
性能基准测试
在我们构建云产品的过程中,核心团队开源了我们内部使用的分析基准。我们将该基准作为在云环境和版本中运行的关键性能测试之一,以便更好地了解数据库在不同配置、云提供商环境和不同版本中的性能表现。我们预计,与物理机(Bare metal)和本地固态硬盘相比,访问对象存储的速度会慢一些,但我们仍然并通过并行化、预取和其他优化措施来实现可交互的,优化过的性能表现(请参阅我们的见面会讲座,了解如何使用ClickHouse将对象存储的读取速度提高100倍)。
每次重大更新时,我们都会更新结果,并在benchmarks.clickhouse.com上公开发布。下面的截图显示了ClickHouse云服务在无共享配置下的性能与一些不同规模的自我管理设置的对比。这里最快的基准是运行在AWS m5d.24xlarge实例上的ClickHouse服务器,该实例使用48个线程执行查询。如您所见,对于基准中的各种简单和复杂查询,使用48个线程的同等云服务表现非常出色。
安全及合规
对我们来说,从一开始就建立对产品的信任非常重要。我们采取三层措施来保护客户的数据。
为安全而构建
我们利用GDPR、SOC 2和ISO 27001等合规框架以及CIS等安全配置标准来构建产品的每个层级。面向互联网的服务受到网络应用防火墙(WAF)的保护。强大的身份验证不仅适用于我们的控制平面和数据库,也适用于我们所有的内部服务和系统。在创建新服务时,会使用基础设施即代码(Infrastructure as code, IaC)来进行部署,以确保配置标准得到一致应用。这包括多个项目,从 AWS 身份和访问管理(IAM)角色、流量路由规则、虚拟专用网络(VPN)配置,到传输中和静态加密以及其他安全配置。我们的内部安全专家会对每个组件进行审查,以确保服务能够高效、有效地运行,同时又安全、合规。
持续地监控
安全性和合规性并不仅是一次性的工作。我们通过漏洞扫描、渗透测试、配置安全日志和警报来持续监控我们的环境,并鼓励行业研究人员通过我们的漏洞赏金计划报告任何潜在问题。此外,我们还通过200多项检查对合规性进行持续监控,其中包括我们的生产环境、公司系统和供应商,以此作为第二道防线,确保我们在技术和流程导向计划方面都恪尽职守。
持续改进
我们持续地根据行业趋势或客户要求增加新的安全功能。ClickHouse数据库已经内置了许多先进的安全功能,包括强大的身份验证和加密、灵活的用户管理RBAC策略以及设置配额和资源使用限制的功能。我们发布的私有预览版具有控制平面上的强身份验证、为默认数据库账户自动生成强密码以及传输中和静态数据加密功能。在公开预览版中,我们增加了IP白名单、AWS PrivateLink支持、通过Google的联合身份验证以及控制平面活动日志。在正式版中,我们为控制平面引入了多因素身份验证。更多安全功能即将推出,以支持更多专业用例和行业。
总的来说,我们对每个云提供商都采用了标准的安全最佳实践。我们在云环境中运行的所有组件都遵循权限最小原则。生产、staging和开发环境彼此完全隔离。每个区域也与所有其他区域完全隔离。对AWS S3、RDS、Route53和SQS等云服务的访问均使用具有严格限制的IAM角色(Role)和IAM策略(Policy)。
下图显示了我们如何使用EKS IAM OIDC identity provider和IAM角色/策略来访问存储客户数据的S3存储桶。每个客户都有一个独立的Kubernetes命名空间(Namespace),其中的服务账户映射到专用的IAM角色。
- EKS在创建Pod时自动加载Service account凭据
- Pod使用ServiceAccount凭据与IAM OIDC Provider进行比对
- Pod使用提供的JWT和IAM角色调用简单令牌服务(Simple Token Service, STS)
- STS为Pod提供用于代入IAM角色(Assume IAM role)的临时安全凭据
我们也将这种模式用于需要访问其他服务的所有组件。
处理客户数据的组件是从网络层面互相完全隔离的。我们的云管理组件也和客户工作负载完全隔离以降低安全风险。
定价和计费
我们花了大约6个月的时间确定定价模式,随后开发了计量(metering)和计费pipeline,并在测试版和正式版之后根据客户反馈不断改进。
按量计费模式
我们知道,我们的用户既然选择了Serverless模式,那么他们就需要一种基于使用量的定价模式。我们考虑了多种模式,最终确定了基于消耗的存储和计算的简单资源定价模式。
我们还考虑过从其他维度来定价,但每种模式都有一些问题,对我们的用户来说并不适用。例如,读/写操作定价很容易理解,但对于分析系统来说并不实用,因为单个查询可能非常简单(对一列进行简单聚合(aggregation)),也可能非常复杂(带有多个聚合和连接的多级选择(join))。根据扫描的数据量定价比较合适,但我们从其他分析系统的用户那里了解到,这种定价方式非常具有惩罚性,会阻碍他们使用系统——这与我们的初衷恰恰相反!最后,我们还考虑了基于不透明的 “工作量单位 “的定价方式,但最终因太难以理解和信任而放弃。
计量和收费引擎
我们按照客户的计算使用量(每分钟)和存储量(每15分钟)收费,因此我们需要跟踪这些维度的实时使用情况,以便显示实时使用指标,并对其进行监控,以确保其不超过某些限制。
ClickHouse已经在内部的系统表中记录了其使用指标。这些数据会被定期从每个客户的ClickHouse服务中查询,并发布到内部和中央ClickHouse计量集群。该集群负责存储所有客户服务的细粒度使用数据,为客户在其服务使用页面上看到的图表提供支持,并将其输入计费系统。
这些用量数据会定期地被从计量集群中收集和汇总,并传输到我们的计量和计费平台m3ter,在那里被转换成计费维度。m3ter原生支持管理各种用例下的承诺(commitment)和预付款。
Scarlett: m3ter是一个管理云计费的Saas服务。Saas和云的兴起催生了Billing as a service的细分领域。类似的产品还有amberflo。
生成账单的流程是这样的:
- 使用指标会被汇总,并通过定价模型计算花费 ,并添加到当前账单中。
- 帐户中的余额(试用、预付额度等)都会被用于支付账单金额(取决于信用额度的开始/结束日期、剩余额度等)。
- 账单总额会一直被重新计算和更新,当检测到重要变化,如信用额度耗尽,将会触发通知(类似于:”您的 ClickHouse 云试用信用额度已超过 75%”)。
- 账单期结束后,我们会重新计算一次,以确保账单日之后收到但是与账单有关的使用指标被计算在内。
- 当前账单会被关闭,帐户余额不足以支付的金额都将添加到新的Stripe的账单中,并从信用卡中扣除。
- 打开新账单,开始汇总新账单期的用量和费用。
- 帐户管理员可以保存信用卡信息,进行现用现付。我们使用Stripe的用户界面组件,确保敏感的信用卡信息安全地直接发送到Stripe。
AWS Marketplace
2022 年 12 月,ClickHouse开始通过AWS Marketplace提供集成计费服务。AWS的定价模式与”现用现付(Pay as you go)”模式相同,但Marketplace用户通过其AWS账户对ClickHouse的使用付费。为了更好地与AWS的集成,我们使用了Tackle,它提供了与所有主要云提供商集成的统一API层,大大减少了构建多云基础设施产品时的整体开发工作量和上市时间。当新用户通过AWS注册时,Tackle会完成握手并将其重定向到ClickHouse云。Tackle还提供API,用于从m3ter向AWS报告账单。
用户界面和产品分析
对我们来说,为客户提供最好用户界面非常重要。为了实现这一目标,我们需要了解客户是如何使用我们的用户界面的,并确定哪些界面运行良好,哪些界面容易混淆,哪些界面需要改进。对客户行为进行更多观察的一种方法是使用事件日志系统。幸运的是,我们内部有最好的OLAP数据库!所有网页用户界面点击和其他产品使用事件都存储在ClickHouse Cloud中运行的ClickHouse服务中,工程和产品团队都依靠这些细粒度数据来评估产品质量并分析使用和采用情况。我们将这些事件的一小部分报告给Segment,这有助于我们的营销团队观察所有接触点(touchpoint)的用户旅程和转换情况。
我们使用Apache Superset作为ClickHouse的可视化层,以便在一个地方查看所有数据。这是一款功能强大、易于使用的开源BI(Business Intelligence)工具,非常适合我们的需求。由于这种设置可以聚合来自不同系统的数据,这对ClickHouse Cloud的运行至关重要。例如,我们使用此设置来跟踪转化率、调整自动伸缩、控制AWS基础设施成本,并作为我们每周内部会议的报告工具。在ClickHouse的支持下,我们永远不必担心系统会因”数据过多”而超载!
总结
我们在构建ClickHouse Cloud的过程中学到了很多。如果要一一列举的话,对我们来说最重要的收获有以下几点。
云并不是真正“弹性”的。尽管我们认为公有云是弹性和无限的,但在大规模情况下则并非如此。重要的是,在设计时要考虑到大规模部署,了解各种云厂商的限制(包括各种人为施加的限制,如资源的quota等),并确保进行大规模测试以找出基础设施中的瓶颈。例如,我们在进入公开测试版之前就遇到了实例可用性问题[*]、IAM角色的限制,以及使用大规模测试时遇到的其他问题,这促使我们采用了蜂窝架构(cellular architecture)。
Scarlett: 在创建AWS EC2实例时,并不是每一次都能保证创建成功。有时可能因为该区域/可用区缺乏足够的物理资源而导致实例创建失败,这在冷门区域和较大实例上会更常见。
除了功能性需求外,可靠性和安全性也是需求。在新功能开发与不影响可靠性、安全性和可用性之间找到平衡点非常重要。不断添加新功能是很诱人的,尤其是在产品的早期开发阶段,但在早期做出的架构决定会对后续发展产生巨大影响。
自动化一切。测试(用户测试、功能测试、性能测试),构建CI/CD Pipeline以快速安全地部署所有更改。使用Terraform来配置EKS集群等静态基础设施,同时使用ArgoCD来配置动态基础设施,因为它可以让您在一个地方看到基础设施中正在运行的内容。
设定激进的目标。我们的目标是在一年内构建ClickHouse Cloud。我们提前确定了里程碑(5 月、10 月、12 月),然后规划了在各个时间点的可行方案。我们必须决定每个里程碑中哪些是最重要的功能,有时这种决定是艰难的,在必要的时候,我们会根据需求消减功能。我们使用类似栈的思想来按照优先级管理每个版本的功能,所以当我们不得不削减时,我们能够毫不犹豫地放弃最底层的功能。
关注到达市场的时间(Time to market)。要想快速开发产品,非常关键的一点是评估并决定哪些功能需要自己构建,又有哪些可以购买现成的解决方案。例如,我们没有自己开发计费(metering)和Marketplace集成,而是利用m3ter和Tackle帮助我们更快地推出基于用量的定价和Marketplace计费。如果我们不与其他公司合作,并将工程精力集中在最核心的创新上,我们就不可能在一年内开发出我们的产品。
倾听用户的声音。我们很早就将用户作为设计合作伙伴引入我们的平台。我们的私人预览版有 50 名用户,我们邀请他们免费使用我们的服务以提供反馈。这是一个非常成功的项目,它让我们迅速了解到哪些方面是可行的,哪些方面是我们在公测过程中需要调整的。在公测期间,我们再次放下手中的笔,开始了倾听之旅。在正式版的开发的过程中,我们调整了定价模式,并为开发人员推出了专门服务,以消除摩擦,满足用户需求。
跟踪并分析云成本。低效地使用云基础设施是很容易的,但结果就是每月支付大笔账单。在构建和设计产品时,不应事后才考虑成本效益,而应将其作为一个重要组成部分。无论是使用EC2、EKS、网络还是S3等存储时,都应遵循使用云服务的最佳实践。例如:我们在S3中发现了1PB的垃圾数据,后来发现是由于mutlipart上传失败造成的。我们开启了TTL以确保这种情况不再发生。
Scarlett: 尤其是对于Startup来说,每个工程师,包括new grad就应有成本的思想,并且费用估计应当作为deisgn doc和design review的一部分。我相信很多人会有过类似的体会——我知道云服务很贵,但是没想到这么贵。最近科技行业不景气,很多公司也在重新评估在云服务上的费用。
结论
我们的目标是在一年内建立ClickHouse Cloud,我们做到了,但也遇到了一些挫折和绕路。最后,我们一如既往地感谢我们能够利用的许多开源工具,这让我们更加自豪地成为开源社区的一员。自发布以来,我们看到了用户的热烈反响,我们非常感谢参与我们的私人预览版和测试版的每一位用户,以及自正式版发布以来加入我们的每一位用户。
如果您想试用ClickHouse Cloud,我们将在30天试用期内提供300美元的信用额度,以帮助你开始使用。如果你对ClickHouse或ClickHouse Cloud有任何疑问,请加入我们的社区Slack频道或在GitHub上参与我们的开源社区。我们很乐意听取您对ClickHouse Cloud的使用体验的反馈意见,以及我们如何为您提供更好的服务!
今天就开始使用ClickHouse Cloud并获得300美元的信用额度。30 天试用期结束后,您可以继续使用现用现付计划,或联系我们了解更多基于数量的折扣。请访问我们的定价页面了解详情。
发表回复/Leave a Reply