HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

HighLoad++ 莫斯科 2018 年,国会大厅。 9月15日 00:XNUMX

摘要和演示: http://www.highload.ru/moscow/2018/abstracts/4066

Yuri Nasretdinov(VKontakte):报告会讲我们公司实施ClickHouse的经验——为什么我们需要它,我们存储了多少数据,我们如何编写等等。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

其他材料: 使用 Clickhouse 替代 ELK、Big Query 和 TimescaleDB

尤里·纳斯雷迪诺夫: - 大家好! 我的名字是尤里·纳斯雷迪诺夫(Yuri Nasretdinov),正如我已经被介绍过的那样。 我在 VKontakte 工作。 我将讨论如何将数据从我们的服务器群(数万)插入到 ClickHouse 中。

什么是日志以及为什么收集它们?

我们将告诉您什么:我们做了什么,为什么我们需要“ClickHouse”,为什么我们选择它,在不进行任何特殊配置的情况下您大约可以获得什么样的性能。 我将进一步告诉您有关缓冲表的信息、我们遇到的问题以及我们从开源开发的解决方案 - KittenHouse 和 Lighthouse。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

为什么我们需要做任何事情(VKontakte 上一切都很好,对吧?)。 我们想要收集调试日志(那里有数百 TB 的数据),也许不知何故计算统计数据会更方便; 我们拥有一支由数万台服务器组成的舰队,所有这些工作都需要通过它们来完成。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

我们为什么决定? 我们可能有存储日志的解决方案。 这里——有这样一个公共的“后端VK”。 我强烈建议订阅它。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

什么是日志? 这是一个返回空数组的引擎。 VK 中的引擎就是其他人所说的微服务。 这是一个微笑的贴纸(很多人喜欢)。 为何如此? 嗯,再听听!

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

可以用什么来存储日志? 不能不提哈杜普。 然后,例如Rsyslog(将这些日志存储在文件中)。 迷幻剂。 谁知道LSD是什么? 不,不是这种LSD。 也分别存储文件。 嗯,ClickHouse 是一个奇怪的选择。

Clickhouse 和竞争对手:要求和机会

我们想要什么? 我们希望确保不必过多担心操作,以便它开箱即用,最好使用最少的配置。 我们想写很多,而且写得很快。 我们希望将其保留数月、数年,即很长一段时间。 我们可能想了解一些问题,他们来找我们并说“这里有些东西不起作用”,那是 3 个月前的事了),我们希望能够看到 3 个月前发生了什么“ 数据压缩——很明显为什么它会是一个优点——因为它减少了占用的空间量。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

我们有一个这样有趣的需求:我们有时会写入一些命令的输出(例如日志),它很容易就超过 4 KB。 如果这个东西通过 UDP 工作,那么它就不需要花费......它不会有任何连接的“开销”,对于大量服务器来说,这将是一个优点。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

让我们看看开源为我们提供了什么。 首先,我们有日志引擎——这是我们的引擎; 原则上,他可以做任何事情,甚至可以写长行。 好吧,它不会透明地压缩数据 - 如果我们愿意,我们可以自己压缩大列......当然,我们不想(如果可能的话)。 唯一的问题是,他只能给出适合他记忆的内容; 要阅读其余部分,您需要获取该引擎的binlog,因此需要相当长的时间。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

还有哪些其他选择? 例如,“哈杜普”。 易于操作...谁认为 Hadup 很容易设置? 当然,录音是没有问题的。 阅读时,有时会产生疑问。 原则上,我会说可能不会,特别是对于日志。 长期存储——当然,是的,数据压缩——是的,长字符串——很明显你可以记录。 但大量服务器的录制……你还是得自己做点什么!

Rsyslog。 事实上,我们将它用作备份选项,以便我们可以在不转储 binlog 的情况下读取它,但它不能写入长行;原则上,它不能写入超过 4 KB。 您必须自己以同样的方式进行数据压缩。 读取将来自文件。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

然后是 LSD 的“badushka”开发。 本质上与“Rsyslog”相同:它支持长字符串,但它不能通过 UDP 工作,事实上,不幸的是,因此,很多东西需要在那里重写。 LSD 需要重新设计,以便能够从数万台服务器进行记录。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

和这里! 一个有趣的选择是 ElasticSearch。 怎么说? 他阅读做得很好,也就是说,他读得很快,但写作不太好。 首先,如果它压缩数据,它的强度就非常弱。 最有可能的是,完整搜索需要比原始卷更大的数据结构。 操作起来比较困难,而且经常会出现问题。 再说一次,在 Elastic 中录制 - 我们必须自己做所有事情。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

这里 ClickHouse 当然是一个理想的选择。 唯一的问题是从数万台服务器进行记录是一个问题。 但至少有一个问题,我们可以尝试以某种方式解决它。 报告的其余部分就是关于这个问题的。 您对 ClickHouse 有何期望?

我们要如何插入它? 合并树

你们当中谁没有听说过或不知道“ClickHouse”? 我需要告诉你,不是吗? 非常快。 那里的插入 - 每秒 1-2 GB,每秒高达 10 GB 的突发实际上可以承受这种配置 - 有两个 6 核 Xeon(也就是说,甚至不是最强大的),256 GB RAM,20 TB在 RAID 中(未配置,默认设置)。 ClickHouse 开发人员 Alexey Milovidov 可能坐在那里哭泣,因为我们没有配置任何东西(一切都像我们那样工作)。 因此,如果数据被很好地压缩,则可以获得每秒约6亿行的扫描速度。 如果您确实喜欢文本字符串上的 % - 每秒 100 亿行,也就是说,它看起来相当快。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

我们要如何插入它? 嗯,您知道 VK 使用 PHP。 我们将通过 HTTP 将每个 PHP 工作线程插入“ClickHouse”中的每条记录的 MergeTree 表中。 谁认为这个方案有问题? 由于某种原因,并不是每个人都举手了。 让我告诉你。

首先,有很多服务器 - 因此,会有很多连接(不好)。 那么向 MergeTree 插入数据的频率最好不要超过每秒一次。 谁知道为什么? 好吧好吧。 我会告诉你更多关于这一点的信息。 另一个有趣的问题是,我们不做分析,我们不需要丰富数据,我们不需要中间服务器,我们想要直接插入“ClickHouse”(最好 - 越直接越好)。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

那么,MergeTree 中的插入是如何完成的呢? 为什么插入频率最好不要超过每秒一次或更少? 事实上,“ClickHouse”是一个列式数据库,按主键升序对数据进行排序,当您进行插入时,会创建至少等于数据排序的列数的文件数量按主键的升序排列(创建一个单独的目录,每次插入都会在磁盘上创建一组文件)。 然后下一个插入到来,并在后台将它们组合成更大的“分区”。 由于数据是排序的,因此可以“合并”两个排序的文件而不消耗太多内存。

但是,正如你可能猜到的,如果你每次插入都写10个文件,那么ClickHouse(或你的服务器)很快就会结束,所以建议大批量插入。 因此,我们从未将第一个方案投入生产。 我们立即推出了一个,这里的第二个有:

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

这里想象一下,我们启动了大约一千台服务器,只有 PHP。 每台服务器上都有我们的本地代理,我们称之为“Kittenhouse”,它与“ClickHouse”保持一个连接,并每隔几秒插入数据。 不将数据插入到 MergeTree 中,而是插入到缓冲表中,这正是为了避免立即直接插入到 MergeTree 中。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

使用缓冲表

这是什么? 缓冲表是一块被分片的内存(即可以频繁地插入其中)。 它们由多个片段组成,每个片段都作为一个独立的缓冲区,并且它们被独立地刷新(如果缓冲区中有很多片段,那么每秒会有很多插入)。 可以从这些表中读取 - 然后您读取缓冲区和父表内容的并集,但此时写入被阻止,因此最好不要从那里读取。 而且缓冲表显示出非常好的QPS,也就是说,高达3QPS你在插入时根本不会有任何问题。 显然,如果服务器断电,那么数据可能会丢失,因为它仅存储在内存中。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

同时,带有缓冲区的方案使 ALTER 变得复杂,因为您首先需要使用旧方案删除旧的缓冲表(数据不会在任何地方消失,因为在删除表之前它会被刷新)。 然后你“改变”你需要的表并再次创建缓冲表。 因此,虽然没有缓冲表,但您的数据不会流向任何地方,但您至少可以在本地将其保存在磁盘上。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

Kittenhouse 是什么以及它是如何工作的?

小猫屋是什么? 这是一个代理。 猜猜是什么语言? 我在报告中收集了最炒作的主题 - “Clickhouse”,走吧,也许我会记得别的东西。 是的,这是用 Go 写的,因为我真的不知道如何用 C 写,我不想。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

因此,它与每个服务器保持连接并可以写入内存。 例如,如果我们将错误日志写入Clickhouse,那么如果Clickhouse没有时间插入数据(毕竟,如果写入太多),那么我们不会膨胀内存 - 我们只是扔掉其余的。 因为如果我们每秒写入几千兆位的错误,那么我们可能会丢弃一些错误。 小猫屋可以做到这一点。 另外,它可以执行可靠的传递,即写入本地计算机上的磁盘,并且每次(每隔几秒一次)尝试从该文件传递数据。 起初我们使用常规的值格式 - 不是某种二进制格式,而是文本格式(如常规 SQL 中那样)。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

但后来发生了这样的事。 我们使用可靠的交付,写入日志,然后决定(这是一个条件测试集群)...它被放置了几个小时并重新启动,并且从一千台服务器开始插入 - 事实证明 Clickhouse 仍然有一个“连接上的线程” - 因此,在一千个连接中,主动插入会导致服务器上的平均负载约为一千个。 令人惊讶的是,服务器接受了请求,但过了一段时间数据仍然插入; 但是服务器很难提供服务......

添加nginx

这种针对每个连接线程模型的解决方案是 nginx。 我们在Clickhouse前面安装了nginx,同时设置了两个副本的平衡(我们的插入速度提高了2倍,尽管事实并非如此),并限制了Clickhouse的连接数,上游,因此,超过 50 个连接,似乎插入没有意义。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

然后我们意识到这种方案一般都有缺点,因为我们这里只有一个nginx。 因此,如果这个 nginx 崩溃了,尽管存在副本,我们也会丢失数据,或者至少不会在任何地方写入数据。 这就是我们自己进行负载平衡的原因。 我们也意识到“Clickhouse”仍然适合日志,“恶魔”也开始在“Clickhouse”中写他的日志——说实话,非常方便。 我们仍然将它用于其他“恶魔”。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

然后我们发现了这个有趣的问题:如果你使用非标准的 SQL 模式插入方法,它会强制使用成熟的基于 AST 的 SQL 解析器,这是相当慢的。 因此,我们添加了设置以确保这种情况永远不会发生。 我们做了负载平衡、健康检查,这样如果有人死了,我们仍然会留下数据。 我们现在有相当多的表,我们需要有不同的 Clickhouse 集群。 我们还开始考虑其他用途 - 例如,我们想从 nginx 模块写入日志,但它们不知道如何使用我们的 RPC 进行通信。 好吧,我想教他们如何至少以某种方式发送 - 例如,通过 UDP 在本地主机上接收事件,然后将它们转发到 Clickhouse。

距离解决方案仅一步之遥

最终的方案开始看起来像这样(该方案的第四个版本):在Clickhouse前面的每台服务器上都有nginx(在同一台服务器上),它只是将请求代理到localhost,连接数限制为50件。 这个计划已经很有效了,一切都很好。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

我们就这样生活了大约一个月。 大家都很高兴,他们加表,他们加,他们加……总的来说,事实证明我们添加缓冲表的方式并不是很优化(就这么说吧)。 我们在每张桌子上做了 16 件作品,闪光间隔为几秒钟; 我们有 20 个表,每个表每秒接收 8 次插入 - 此时“Clickhouse”开始......记录开始变慢。 他们甚至没有经过……默认情况下,Nginx 有一个非常有趣的事情,如果连接在上游终止,那么它只会向所有新请求返回“502”。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

在这里,我们(我刚刚查看了 Clickhouse 本身的日志)大约有 XNUMX% 的请求失败了。 因此,磁盘利用率很高,存在大量合并。 嗯,我做了什么? 当然,我没有费心去弄清楚连接和上游到底为什么结束。

用反向代理替换 nginx

我决定我们需要自己管理这个,我们不需要把它留给 nginx - nginx 不知道 Clickhouse 中有哪些表,我用反向代理替换了 nginx,这也是我自己编写的。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

他在做什么? 它基于 fasthttp 库“goshnoy”工作,即快,几乎与 nginx 一样快。 抱歉,Igor,如果您在场的话(注:Igor Sysoev 是一位俄罗斯程序员,创建了 nginx Web 服务器)。 它可以理解这些是什么类型的查询 - INSERT 或 SELECT - 因此,它为不同类型的查询持有不同的连接池。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

因此,即使我们没有时间完成插入请求,“选择”也会通过,反之亦然。 它将数据分组到缓冲表中 - 带有一个小缓冲区:如果有任何错误,语法错误等 - 这样它们就不会极大地影响其余数据,因为当我们简单地插入到缓冲表中时,我们有小“八尺”,所有语法错误只影响这一小块; 在这里它们已经影响了一个大的缓冲区。 小就是1兆字节,也就是说,没有那么小。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

插入同步并本质上替换 nginx,基本上与 nginx 之前所做的事情相同 - 您不需要为此更改本地“Kittenhouse”。 由于它使用 fasthttp,因此速度非常快 - 通过反向代理,您可以每秒发出超过 100 万个请求来进行单次插入。 理论上,您可以一次向 kittenhouse 反向代理插入一行,但我们当然不会这样做。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

该方案开始看起来像这样:“Kittenhouse”,反向代理将许多请求分组到表中,然后缓冲表将它们插入主表中。

Killer 是暂时的解决方案,Kitten 是永久的解决方案

这是一个有趣的问题...你们有人用过fasthttp吗? 谁将 fasthttp 与 POST 请求结合使用? 也许,这确实不应该这样做,因为它默认缓冲请求正文,而我们的缓冲区大小设置为 16 MB。 插入在某个时刻停止了,16MB 的块开始从所有数万台服务器到达,它们在发送到 Clickhouse 之前都在内存中缓冲。 因此,内存耗尽,Out-Of-Memory Killer 来杀死反向代理(或“Clickhouse”,理论上可以“吃”比反向代理更多的东西)。 这个循环又重演了。 这不是一个令人愉快的问题。 尽管我们在运行几个月后才偶然发现了这一点。

我做了什么? 再说一遍,我真的不太想了解究竟发生了什么。 我认为很明显你不应该缓冲到内存中。 尽管我尝试过,但我无法修补 fasthttp。 但我找到了一种方法,这样就不需要修补任何东西,并且我在 HTTP 中提出了自己的方法 - 我称之为 KITTEN。 嗯,这是合乎逻辑的 - “VK”、“Kitten”...还有什么?...

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

如果请求通过 Kitten 方法到达服务器,那么服务器应该按逻辑响应“喵”。 如果他响应了这个,那么就认为他理解这个协议,然后我拦截这个连接(fasthttp有这样的方法),连接进入“raw”模式。 为什么我需要它? 我想控制从 TCP 连接读取数据的方式。 TCP 有一个奇妙的特性:如果没有人从另一端读取数据,那么写入操作就会开始等待,并且内存不会特别消耗在这方面。

所以我一次从大约 50 个客户那里读取信息(从 20 个开始,因为 XNUMX 个绝对应该足够了,即使费率来自另一个 DC)……通过这种方法,消耗量减少了至少 XNUMX 倍,但说实话,我,我无法准确测量出什么时间,因为它已经毫无意义了(已经达到了错误的程度)。 协议是二进制的,即包含表名和数据; 没有 http 标头,因此我没有使用 Web 套接字(我不需要与浏览器通信 - 我制定了一个适合我们需求的协议)。 他一切都变得很好。

缓冲表很悲伤

最近我们发现了缓冲表的另一个有趣的功能。 而且这个问题已经比其他问题痛苦得多了。 让我们想象一下这种情况:您已经在积极使用Clickhouse,您有数十台Clickhouse服务器,并且您有一些请求需要花费很长时间才能读取(比方说,超过60秒); 此时你来执行Alter...同时,在“Alter”之前开始的“selects”将不会包含在该表中,“Alter”将不会启动 - 可能是“Clickhouse”如何工作的一些功能这个地方。 也许这可以解决? 或者说这是不可能的?

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

一般来说,很明显,实际上这并不是一个大问题,但对于缓冲表来说,它变得更加痛苦。 因为,如果,比方说,您的“Alter”超时(并且它可能在另一台主机上超时 - 不是在您的主机上,而是在副本上,例如),那么...您删除了缓冲表,您的“Alter”(或其他主机)超时。然后发生“Alter”错误) - 您仍然需要确保数据继续写入:您创建回缓冲表(根据与父表相同的方案),然后“Alter”经历,最终结束,表的缓冲区开始在架构上与父表不同。 根据“改变”的内容,插入可能不再进入该缓冲表 - 这是非常可悲的。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

还有这样一个标志(也许有人注意到了)——在新版本的Clickhouse中叫做query_thread_log。 默认情况下,在某些版本中有一个。 我们在几个月内积累了 840 亿条记录(100 GB)。 这是因为“插入”被写在那里(也许现在,顺便说一句,它们没有被写)。 正如我告诉你的,我们的“插入”很小 - 我们在缓冲表中有很多“插入”。 很明显,此功能已被禁用 - 我只是告诉您我在我们的服务器上看到的内容。 为什么? 这是反对使用缓冲表的另一个论点! 斯波蒂非常难过。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

谁知道这家伙的名字叫斯波蒂? VK员工举起了手。 好的。

关于“KittenHouse”的计划

计划通常不会共享,对吗? 突然之间,你将无法实现这些目标,并且在别人眼中看起来也不太好。 但我会冒这个险! 我们想要执行以下操作:在我看来,缓冲表仍然是一个拐杖,我们需要自己缓冲插入。 但我们仍然不想在磁盘上缓冲它,所以我们将在内存中缓冲插入。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

因此,当进行“插入”时,它将不再是同步的 - 它已经作为缓冲表工作,将插入到父表中(好吧,有一天)并通过单独的通道报告插入已通过以及哪些插入已通过。没有。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

为什么我不能保留同步插入? 方便多了。 事实是,如果您从 10 个主机插入,那么一切都很好 - 您将从每个主机获得一点,您每秒插入一次,一切都很好。 但我希望这个方案能够工作,例如,从两台机器上运行,以便您可以高速下载 - 也许无法充分利用 Clickhouse,但通过反向代理从一台机器每秒至少写入 100 兆字节 -该方案必须扩展到大量和少量,因此我们不能为每次插入等待一秒钟,因此它必须是异步的。 同样,异步确认应该在插入完成后进行。 我们会知道它是否通过。

最重要的是,在这个方案中我们可以确定插入是否发生。 想象一下这种情况:您有一个缓冲表,您向其中写入了一些内容,然后,假设该表进入只读模式并尝试刷新缓冲区。 数据会去哪里? 它们将保留在缓冲区中。 但我们无法确定这一点 - 如果存在其他错误,导致数据不会保留在缓冲区中怎么办...(地址 Alexey Milovidov,Yandex,ClickHouse 开发人员)还是会保留? 总是? 阿列克谢让我们相信一切都会好起来的。 我们没有理由不相信他。 但无论如何:如果我们不使用缓冲表,那么它们就不会有任何问题。 创建两倍的表也很不方便,尽管原则上没有大问题。 这就是计划。

我们来谈谈读书

现在我们来谈谈阅读。 我们还在这里编写了自己的工具。 看起来,好吧,为什么要在这里编写自己的工具?...谁使用 Tabix? 不知怎的,很少有人举手……谁对 Tabix 的表现感到满意? 嗯,我们对此并不满意,而且查看数据不太方便。 它对于分析来说很好,但仅仅对于查看来说它显然没有优化。 所以我编写了自己的界面。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

很简单——它只能读取数据。 他不知道如何显示图形,他不知道如何做任何事情。 但它可以显示我们需要的东西:比如表有多少行,占用了多少空间(不拆成列),也就是说,一个非常基本的界面就是我们需要的。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

而且它看起来与 Sequel Pro 非常相似,但仅在 Twitter 的 Bootstrap 上制作,并且是第二个版本。 你问:“尤里,为什么是第二个版本?” 哪一年? 2018? 总的来说,我很久以前就为“Muscle”(MySQL)做了这个,只是改变了查询中的几行,它就开始为“Clickhouse”工作,为此特别感谢! 因为解析器与“肌肉”解析器非常相似,并且查询也非常相似 - 非常方便,尤其是一开始。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

嗯,它可以过滤表格,可以显示表格的结构和内容,允许您排序,按列过滤,显示导致结果的查询,受影响的行(结果有多少),即查看数据的基本内容。 相当快。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

还有一个编辑器。 老实说,我试图从 Tabix 窃取整个编辑器,但我做不到。 但不知何故它有效。 原则上就是这样。

“Clickhouse”适合窝点

我想告诉您,尽管存在上述所有问题,Clickhouse 仍然非常适合日志。 最重要的是,它解决了我们的问题 - 它非常快并且允许您按列过滤日志。 原则上,缓冲表表现不佳,但通常没有人知道为什么......也许现在您更清楚哪里会出现问题。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

TCP? 一般来说,在VK中习惯使用UDP。 当我使用 TCP 时……当然,没有人告诉我:“尤里,你在说什么! 你不能,你需要 UDP。” 事实证明TCP并没有那么可怕。 唯一的问题是,如果你写了数以万计的活性化合物,你需要更仔细地准备它; 但这是可能的,而且很容易。

我承诺如果每个人都订阅我们的公共“VK 后端”,我就会在 HighLoad Siberia 上发布“Kittenhouse”和“Lighthouse”...而且你知道,不是每个人都订阅...当然,我不会要求您订阅我们的民众。 你们人还是太多了,甚至可能有人会被冒犯,但还是请订阅(这里我得把眼睛画得像猫一样)。 那是 顺便链接到它。 非常感谢! Github 是我们的 这里。 使用 Clickhouse,您的头发将变得柔软丝滑。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

主持人: - 朋友们,现在提问。 在我们向您颁发感谢状和 VHS 报告后。

尤里·纳斯雷迪诺夫(Yuri Nasretdinov,以下简称YN): – 如果我的报告刚刚结束,你怎么能在 VHS 上录制我的报告?

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

主持人: – 你也无法完全确定“Clickhouse”将如何运作! 朋友们,5分钟提问时间!

问题

观众提问(以下简称Q): - 下午好。 非常感谢您的报告。 我有两个问题。 我将从一些无聊的事情开始:图中“Kittenhouse”名称中的字母 t 的数量(3、4、7...)是否会影响猫的满意度?

阳: - 数量是多少?

Z: – 字母 t。 有 XNUMX 个 t,大约是 XNUMX 个 t。

阳: - 我没修好吗? 嗯,当然可以! 这些是不同的产品——我一直在欺骗你。 好吧,我开玩笑的——没关系。 啊,就在这里! 不,是同一件事,我打错了。

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

Z: - 谢谢。 第二个问题很严肃。 据我了解,在 Clickhouse 中,缓冲表仅存在于内存中,不会缓冲到磁盘,因此并不持久。

阳: - 是的。

Z: – 同时,您的客户端缓冲到磁盘,这意味着对这些相同日志的传送有一定的保证。 但 Clickhouse 并不能保证这一点。 解释一下保证是如何进行的,由于什么原因?..以下是该机制的更详细信息

阳: – 是的,理论上这里不存在矛盾,因为当 Clickhouse 倒塌时,你实际上可以通过一百万种不同的方式来检测它。 如果 Clickhouse 崩溃了(如果它错误地结束了),粗略地说,你可以倒回你写下的一些日志,然后从一切都很好的那一刻开始。 假设你倒回一分钟,即认为你在一分钟内冲掉了所有内容。

Z: – 也就是说,“Kittenhouse”可以更长时间地保持窗户,并且在跌倒时能够识别并倒回窗户?

阳: ——但这只是理论上的。 实际上,我们不这样做,可靠的交付是从零到无限次。 但平均一个。 我们很满意,如果 Clickhouse 由于某种原因崩溃或服务器“重新启动”,那么我们会损失一点。 在所有其他情况下,什么都不会发生。

Z: - 你好。 从一开始,我就认为您确实从报告的一开始就使用了 UDP。 你有http,所有这些......据我所知,你描述的大多数问题都是由这个特定的解决方案引起的......

阳: – 我们使用 TCP 做什么?

Z: - 基本上是的。

阳: - 号

Z: – 你在使用 fasthttp 时遇到了问题,在使用连接时遇到了问题。 如果您只使用 UDP,您会节省一些时间。 好吧,长消息或其他什么都会有问题......

阳: - 什么?

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

Z: – 对于长消息,由于它可能不适合 MTU,还有其他东西......好吧,可能存在它们自己的问题。 问题是:为什么不用UDP?

阳: – 我相信开发TCP/IP的作者比我聪明得多,比我更了解如何序列化数据包(以便它们走),同时调整发送窗口,不使网络过载,反馈什么没有被读取,不包括在另一边...在我看来,所有这些问题都存在于 UDP 中,只是我必须编写比我已经编写的代码更多的代码才能自己实现同样的事情,而且很可能不好。 我什至不太喜欢用 C 语言编写,更不用说……

Z: - 就是方便! 发送成功,无需等待任何事情 - 它是完全异步的。 返回一条通知,表明一切正常 - 这意味着它已到达; 如果它不来,那就意味着情况不好。

阳: – 我两者都需要 – 我需要能够发送有送达保证和无送达保证的两者。 这是两种不同的场景。 我不需要丢失一些日志或在合理范围内不丢失它们。

Z: – 我不会浪费时间。 这需要更多地讨论。 谢谢。

主持人: – 谁有疑问 – 双手举向天空!

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

Z: - 你好,我是萨莎。 在报告中间的某个地方,出现了一种感觉,除了 TCP 之外,还可以使用现成的解决方案 - 某种 Kafka。

阳: – 嗯...我告诉过你我不想使用中间服务器,因为...在Kafka中,事实证明我们有一万台主机; 事实上,我们还有更多——数以万计的主机。 在没有任何代理的情况下使用 Kafka 也可能会很痛苦。 此外,最重要的是,它仍然会带来“延迟”,它会提供您需要的额外主机。 但我不想拥有它们——我想要……

Z: “但最终结果还是那样。”

阳: – 不,没有主人! 这一切都适用于 Clickhouse 主机。

Z: - 嗯,还有“Kittenhouse”,正好相反 - 他住在哪里?

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

阳: – 在 Clickhouse 主机上,它不会向磁盘写入任何内容。

Z: - 让我们假设一下。

主持人: - 你满意吗? 我们可以给你工资吗?

Z: - 是的你可以。 事实上,为了得到同样的东西,有很多拐杖,现在 - 之前关于 TCP 主题的答案在我看来与这种情况相矛盾。 感觉一切都可以在更短的时间内用我的膝盖完成。

阳: – 还有为什么我不想使用 Kafka,因为 Clickhouse Telegram 聊天中有很多抱怨,例如来自 Kafka 的消息丢失了。 不是来自Kafka本身,而是来自Kafka和Clickhaus的整合; 或者有什么东西没有连接到那里。 粗略地说,那就需要为Kafka编写一个客户端了。 我认为没有更简单或更可靠的解决方案。

Z: – 告诉我,你为什么不尝试排队或乘坐某种公共巴士? 既然您说通过异步,您可以通过队列发送日志本身并通过队列异步接收响应?

HighLoad++,Yuri Nasretdinov (VKontakte):VK 如何将数据从数万台服务器插入 ClickHouse

阳: – 请建议可以使用哪些队列?

Z: – 任何,即使不能保证它们是有序的。 某种 Redis、RMQ...

阳: – 我有一种感觉,即使在拉出 Clickhouse 的一台主机(在多台服务器的意义上)上,Redis 很可能也无法拉出如此大的插入量。 我无法用任何证据来支持这一点(我还没有对其进行基准测试),但在我看来,Redis 并不是最好的解决方案。 原则上,这个系统可以被认为是一个临时的消息队列,但它是专门为“Clickhouse”量身定制的

主持人: – 尤里,非常感谢你。 我建议在此结束问题和答案,并说明我们将把这本书送给那些提出问题的人。

阳: – 我想送给第一个提出问题的人一本书。

主持人: - 精彩的! 伟大的! 极好! 多谢!

一些广告🙂

感谢您与我们在一起。 你喜欢我们的文章吗? 想看更多有趣的内容? 通过下订单或推荐给朋友来支持我们, 面向开发人员的云 VPS,4.99 美元起, 我们为您发明的入门级服务器的独特模拟: VPS (KVM) E5-2697 v3(6 核)10​​4GB DDR480 1GB SSD 19Gbps XNUMX 美元或如何共享服务器的全部真相? (适用于 RAID1 和 RAID10,最多 24 个内核和最多 40GB DDR4)。

Dell R730xd 在阿姆斯特丹的 Equinix Tier IV 数据中心便宜 2 倍? 只有这里 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 电视低至 199 美元 在荷兰! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - 99 美元起! 阅读 如何建设基础设施公司同级使用价值730欧元的Dell R5xd E2650-4 v9000服务器一分钱?

来源: habr.com

添加评论