当前位置: 首页 > 后端技术 > PHP

Clickhouse架构与应用

时间:2023-03-29 16:41:25 PHP

内容大纲:背景;Clickhouse介绍;Clickhouse架构和性能;好未来的Clickhouse实践;建设和规划;参考。背景在日志中心发展初期,日志的检索和分析主要基于elasticsearch。随着越来越多的服务接入日志中心,数据量逐渐增加。基于日志的分析和监控告警需求越来越复杂。使用elasticsearch很难满足,需要根据需求场景选择合适的数据库。我们需要的:数据量会很大,需要分布式;支持实时写入,支持快速计算,短时间内完成计算;强大的sql能力,实时指标sql;人力有限,运维需求简单;高效压缩比存储,有限的服务器,用更少的服务器存储更多的数据;基于以上特点,我们选择了Clickhouse,接下来我们将介绍Clickhouse的特点、系统架构和使用方法。Clickhouse介绍1.Clickhouse的特点=================图2-1Clickhouse的特点可以看到,Clickhouse的特点正是我们所需要的。下面详细介绍核心特性:1)完善的DBMS功能:ClickHouse具有完善的管理功能,所以可以称之为DBMS(DatabaseManagementSystem,数据库管理系统),而不仅仅是一个数据库。作为DBMS,它具有一些基本功能,如:DDL(数据定义语言):可以在不重启服务的情况下动态创建、修改或删除数据库、表和视图;DML(DataManipulationLanguage):可以动态查询、插入、修改或删除数据;权限控制:可以根据用户粒度设置对数据库或表的操作权限,保证数据安全;数据备份与恢复:提供数据备份导出与导入恢复机制,满足生产环境需求;分布式模式管理:提供集群模式,可以自动管理多个数据库节点。2)列存储和数据压缩列存储和数据压缩是高性能数据库必不可少的特性。让查询更快最简单有效的方法就是减少数据扫描范围和数据传输的大小,而列式存储和数据压缩可以帮助我们实现以上两点。由于Clickhouse是真正意义上的列式存储,每一列都在不同的文件下,所以文件的数据类型是一致的,可以更有效地进行压缩。3)向量化执行引擎向量化执行是以列存储为前提的。主要思路是每次从磁盘中读取一批列,这些列以数组的形式组织起来。每个next通过for循环处理列数组。这样做可以大大减少下一次调用的次数。相应的CPU利用率得到了提高,并且数据也被组织在一起。可以进一步利用CPU硬件的特性,如SIMD,将所有数据加载到CPU的缓存中,提高缓存命中率,提高效率。在列存储和向量化执行引擎的双重优化下,查询执行速度将有巨大的飞跃。4)关系模型和SQL查询ClickHouse是一个关系型数据库。它可以支持几乎90%的sql作为查询语句,如groupby、orderby等。5)多样化的表引擎ClickHouse和mysql一样,也将存储部分抽象出来,将存储引擎作为一个独立的接口。因此,Clickhouse实现了多种表引擎,如mergetree、log、memory等多种类型的引擎。每个表引擎都有自己的特点。用户可以根据实际业务场景的需求,选择合适的表引擎使用。6)多线程、分布式的ClickHouse几乎具备现代高性能数据库的所有典型特征。可以说,提高性能的手段已经一一用尽。对于多线程、分布式等广泛使用的技术,自然是用不上的。下一个。7)多主架构HDFS、Spark、HBase、Elasticsearch等分布式系统均采用Master-Slave主从架构,由一个控制节点作为Leader统筹全局。ClickHouse与其他数据库的不同之处在于其集群架构,这使其成为多主架构。8)在线查询ClickHouse采用LSM树结构,所以ClickHouse的插入量可以很大。同时,Clickhouse内部的优化使其在复杂的查询场景下能够极速响应,无需对数据进行任何预处理。实现了实时数仓的效果9)数据分片和分布式查询Clickhouse具有分布式能力,天然支持数据分片。数据分片是数据的水平切分。这是在面对海量数据的场景下,是解决存储和查询瓶颈的有效手段。ClickHouse不像其他分布式系统那样具有高度自动化的分片功能。ClickHouse提供了LocalTable和DistributedTable的概念。本地表相当于数据分片。分布式表本身不存储任何数据,它是本地表的访问代理,其功能类似于分库中间件。借助分布式表,可以通过代理访问多个数据分片,从而实现分布式查询。2.Clickhouse常见应用场景电信行业用于存储数据和使用统计数据;新浪微博用于用户行为数据记录和分析;用于广告网络、RTB、电商用户行为分析;日志分析;探测与遥感信息挖掘;商业智能;网络游戏、物联网数据处理及价值数据分析;最大的应用来自Yandex.Metricca,Yandex的统计分析服务。Clickhouse架构及性能Clickhouse的集群架构不同于其他数据集群。它的集群能力是表级别的,而我们熟悉的大数据系统,比如Hadoop系列集群,是服务级别的。比如在一个hdfs集群中,所有的文件都会被分片备份;在Clickhouse集群中,你可以在创建表时决定是否使用它,这意味着单个Clickhouse节点实际上可以存活。有其他大数据经验的人可能会觉得这种设计有点奇怪,后面我们会从单机架构到集群架构进行详细介绍。=========================================================================================================================================================================================================1、Clickhouse单机架构设计官方对Clickhouse架构的介绍比较少。根据已有经验和外部资料,根据自己的理解还原clickhouse架构:图3-1clickhouse单机架构图1)Parser和InterpreterParser和Interpreter是非常重要的两组接口:Parser解析器形成AST语法树SQL语句的递归方式,不同类型的SQL会调用不同的parse实现类。Interpreter解释器负责解释AST并进一步创建查询执行管道。Interpreter解释器的作用类似于Service服务层,起到衔接整个查询过程的作用。它会根据解释器的类型聚合它需要的资源。首先,它解析AST对象;然后执行“业务逻辑”(如分支判断、设置参数、调用接口等);最后返回IBlock对象,并以线程的形式建立查询执行管道。2)表引擎表引擎是ClickHouse的一个显着特点。上面说了clickhouse有很多种表引擎。不同的表引擎由不同的子类实现。表引擎使用IStorage接口,定义了DDL(如ALTER、RENAME、OPTIMIZE、DROP等)、read、write方法,分别负责数据的定义、查询和写入。3)DataType负责DataType数据的序列化和反序列化。根据不同的数据类型,IDataType接口会有不同的实现类。DataType虽然会转发和反序列化数据,但不会直接和内存或磁盘交互,而是交给Column和Filed处理。4)Column和FieldColumn和Field是ClickHouse数据最基本的映射单元。作为一个100%列式存储的数据库,ClickHouse是按列存储数据的,内存中的一列数据用一个Column对象表示。Column对象分为接口和实现两部分。在IColumn接口对象中,定义了对数据进行各种关系操作的方法,如插入数据的insertRangeFrom和insertFrom方法,分页的cut方法,过滤方法的filter等,这些方法的具体实现对象由相应的对象实现到不同的数据类型,例如ColumnString、ColumnArray和ColumnTuple。大多数情况下,ClickHouse会以整列的形式操作数据,但也有例外。如果需要操作单个特定值(即单个列中的一行数据),则需要使用Field对象,它代表单个值。不同于Column对象的泛化设计思想,Field对象使用了聚合设计模式。Field对象内部聚合了Null、UInt64、String、Array等13种数据类型和相应的处理逻辑。5)BlockClickHouse内部的数据操作是针对Block对象进行的,采用流的形式。Column和Filed虽然构成了数据的基本映射单元,但仍然缺少一些与实际操作对应的必要信息,如数据的类型、列名等。所以ClickHouse设计了Block对象,可以看做是数据表的一个子集。Block对象的本质是由数据对象、数据类型和列名组成的三元组,即Column、DataType和列名字符串。Column提供了读取数据的能力,而DataType知道如何转发和反序列化,所以Block在这些对象的基础上实现了进一步的抽象和封装,从而简化了整个使用过程,只需要通过Block对象就可以完成一系列数据操作。在具体实现过程中,Block并没有直接聚合Column和DataType对象,而是通过ColumnWithTypeAndName对象进行间接引用。2.Clickhouse集群架构设计Clickhouse是一个集群,通过配置clickhouse_remote_servers来管理集群。在配置中,可以配置集群名称,集群需要的节点信息,通过这些信息可以配置分片和复制机制。简单配置为例:trueclickhouse-node19000clickhouse-node29001trueclickhouse-node39000clickhouse-node49001.........以上集群配置完成后,如果要使用Clickhouse的集群能力,需要使用ReplicatedMergeTree+Distributed引擎,也就是“本地表+分布式表”,所以可以实现多分片和多副本;下面详细介绍ReplicatedMergeTree引擎和Distributed引擎。1)Replicated*MergeTree引擎首先需要引入MergeTree引擎,它也是Clickhouse存储数据的核心引擎。上面提到的特性主要针对该引擎进行描述。MergeTree引擎在MergeTree的基础上扩展了一些功能引擎,包括对ReplacingMergeTree、SummingMergeTree等MergeTree家族引擎的支持。具体参见官网mergetree引擎介绍。没有复制的MergeTree引擎可以看作是一个独立的引擎,也就是说,它们存在于单个节点上。ReplicatedMergeTree的使用是通过Zookeeper调整MergeTree引擎的数据,达到复制的效果。比如上面的配置,我们可以先在cluster1的每个节点上创建一张ReplicatedMergeTree表。通过配置文件我们可以看到Clickhouse-node1和Clickhouse-node2在同一个shard,每个shardtag都包含Replica代表复制节点。这时我们在建表的时候,指定两个副本在同一个zokeeper目录下,那么写到node1的数据会复制到node2,写到node2的数据会同步到node1,实现预期的复制影响。至此,每个节点上的本地表已经完成,但是如何汇总多个分片的数据,就需要下面的分布式引擎了。2)分布式引擎使用分布式引擎的表本身不存储任何数据,但允许在多台服务器上进行分布式查询处理,读取自动并行。读取时,会用到远程服务器上的表索引(也就是我们上面使用的Replicated*MergeTree引擎)。在读写数据时,如果使用分布式表,可以根据配置文件中配置的分片方案,从不同的分片中读写数据,达到数据分片的效果。比如我们读取数据的时候,我们是通过分布式引擎表来读取的。此时会读取集群中各个分片的数据进行汇总计算。请注意,此块中会有深度分页。有的SQL可以先在每个节点上执行,然后再对查询节点进行结果聚合,有的则不能进行结果聚合。所有数据都要同步到查询节点,查询节点统一聚合。在这种情况下,需要根据具体的数据情况进行优化。图3-2本地表加分布式表的查询流程图图3-2是一个2-shard2-copy的架构,采用Replicated*MergeTree+Distributedengine模式。红色数字代表节点,即节点1和2互为副本,节点3和4互为副本。图中events是一张Distributedengine表,也叫分布式表;events_local是一张Replicated*MergeTree引擎表,也叫本地表。图中只在3号节点创建分布式表,线上环境一般在每个节点上创建分布式表(不消耗资源,因为分布式表不存储数据)。执行查询时,访问节点的分布式表。在该图中,访问了节点3的分布式表。然后分布式表会分别读取两个分片的数据。这里读取的是节点3和节点2的本地表数据,这两个节点相加就是完整的数据。汇总查询后,返回结果(ResultSet)。3、Clickhouse性能1)插入:单机插入速度100-150M/s;2)查询:单字段groupby无索引,查询1亿条数据耗时2.324s。使用索引,查询时间为0.101秒。可见Clickhouse的查询速度是极快的,市面上常见的数据库基本达不到这个性能;3)其他:并发,官网默认配置为100。由于是大数据分析数据库,主要适用于Olap场景,对并发的支持稍差。多个大数据查询可能会直接占满CPU等资源,所以实际并发达不到100。好未来Clickhouse实践图4-1Clickhouse在线架构图1.业务场景目前好未来除了我们部门,已经有多个其他部门的商务聚会。1)部门使用平台:日志中心、owl、groundhog、grafana等。使用方式:我们通过flink、spark、gohangout等工具,通过kakfa消费需要的数据,写入clickhouse,然后执行通过clickhouse聚合查询来展示数据。比如Groundhog主要是通过网关数据进行聚合,可以看到每个域名、url或者服务器的调用次数,以及请求的耗时。再比如直播数据,就是消费直播报表日志,使用grafana展示数据。2)其他部门除了本部门外,还有其他业务方、数据研发部门、数据中台等也在使用。数据研发部主要将hive中的热点数据通过spark/dataX同步到Clickhouse。然后将数据通过天书天选等平台展示给分析师,提高了查询速度。图4-2:Clickhouse使用情况图2、存储状态图4-3单节点数据存储情况以上数据第一列为库名,第二列为行数,第三列为压缩前大小,第四列是尺寸后的压缩。可以看到单个节点已经有多个数据库,TB级,百亿行。目前有6个数据节点,意味着在集群中,数据量需要乘以6,这意味着一些图书馆的行数已经达到1000亿行,容量已经达到了100吨。建设与规划1.监控Clickhouse目前没有提供直接的监控接口,但是需要的监控数据会记录在系统数据库中,网上有人通过grafana展示出来。电流监控图如图5-1所示。图5-1clickhouse监控示意图另外,编写了脚本定时检测并重启各个节点。同时,还通过神数平台查看各节点的硬件信息和告警。2.遇到的问题。Clickhouse作为一个olap数据库,在使用过程中或多或少会出现一些问题,比如版本bug、使用不规范、混系问题等。下面主要介绍几个需要持续优化或者业务合作的。问题。其他遇到的一些问题也会在wiki上持续更新:1)大量查询导致服务器负载高,影响业务查询分析:多次复杂查询,命中数据量大。每个查询都需要大量的cpu和内存。会导致服务器负载满载。尤其是内存满了,会导致节点挂掉。解决方案:用户限制,为避免内存满,可以配置max_memory_usage_for_all_queries使其低于服务器实际内存。并且还可以限制用户的并发数,每次查询的数据量等;有些业务无法限制查询数据量,可以加入缓存机制,避免大量大数据查询。2)DDL语句卡住分析:Clickhouse主要支持追加和查询,但是使用mergetree引擎的表可以进行更新和删除。update和delete操作使用altertable语句,也就是说这其实需要ddl的权限。每次发生这样的操作时,数据库都会被锁定,并且会发生更新表等操作。在数据量很大的情况下,如果进行更新操作,整个数据会根据索引情况重新排序,这是一个漫长的过程。Clickhouse的ddl语句底层应该是一个队列。一个不执行,其他的ddl就会卡住。解决方法:尽量减少ddl语句的执行频率,增加执行间隔,或者尽量不执行。3)Zookeeper掉线分析:Clickhouse集群方案非常依赖zk,副本同步机制也依赖zk,导致每次插入数据都要和zk交互,在zk中进行写操作。在高插入并发的情况下,可能会导致zk暂时失联。解决方案:Zookeeper之前是和Clickhouse混在一起的,后来拆分了,情况有所好转。不过目前还是偶尔会出现一些问题,后续我们会继续优化这块地方。zookeeper的服务器性能也会尽可能的提升。申请高配置服务器提升zookeeper性能,使clickhouse不受zookeeper性能影响。3.未来规划想要构建一个高性能稳定的大数据场景数据库,需要的是不断的学习和与业务方的合作。深入了解业务,根据业务场景建表;继续学习clickhouse,根据clickhouse的特点优化SQL;同时也需要业务方的配合,如果大查询频率高,可以考虑使用缓存等机制,也可以在特定场景下使用近似计算。同时特殊场景特殊处理,实现合适的SQL;数据不断增长,查询压力也越来越大,集群隔离,重要业务互不影响;不断完善监测报警机制;clickhouse还有很多强大的功能,以后会尝试使用。参考文献[1]https://clickhouse.tech/docs[2]https://blog.csdn.net/tzs_104...[3]https://www.jianshu.com/p/ab8...