ZooKeeper 避坑实践:SnapCount 设置不合理导致磁盘爆满,服务不可用

news2024/11/15 23:54:58

作者:子葵

背景

在 ZooKeeper 的日常使用过程中,一个令人头疼的问题就是节点的磁盘容量问题,如果由于过大的 TPS 或者不适当的清理策略会导致集群中数据文件,日志文件的堆积,最终导致磁盘爆满,Server 宕机。近期就在线上发现某用户的一个集群在一个时间段内的 TPS 暴增。

在这里插入图片描述

导致磁盘中 snapshot 和 transaction log 文件非常多。

在这里插入图片描述

最终导致磁盘被写满,节点服务不可用。

在这里插入图片描述

本篇通过深入解读 ZooKeeper 数据文件生成机制,以及 ZooKeeper 中和数据文件生成相关的参数,探究一下 解决 ZooKeeper 磁盘问题的最佳实践。

分析

ZooKeeper 中生成的数据文件有哪些?

首先我们需要探究一下 ZooKeeper 对数据进行持久化的基本原理,ZooKeeper 为了保证所有的数据变更不丢失,采用状态机来进行数据的记录和恢复,简单来讲,ZooKeeper 中有一个大 Map 存储所有 Znode,key 就是 Znode 的 Path,value 就是 Znode 中的数据,acl,状态等信息,ZooKeeper 通过在某一时间点对内存中的大 Map 进行序列化得到这一时间点内存中数据的一份快照,同时通过另一个文件,存储在此时间节点之后对这份快照中数据状态的修改操作。

在这里插入图片描述

当 ZooKeeper 节点重启的时候,会通过现有的 snapshot 和 transaction log 进行数据恢复。

在这里插入图片描述

采用这种做法能够很好的保证内存中已变更的数据不会丢失,同时写性能不会有太多损失,在遇到节点宕机之后,能够完整的恢复数据。

从此看来,ZooKeeper 产生的数据文件主要有两类:内存中数据的快照文件,以及存储变更的事务日志文件,这两类文件分别通过配置文件中的 dataDir 和 dataLogDir 进行指定,这也是 ZooKeeper 中占用磁盘空间比较大的两类文件。

当 zk 中数据存储过多或者数据变更非常频繁的情况下,将内存中的存储的 snapshot 序列化到文件中,以及数据变更产生的事务日志文件就会很多很大,如果没有配置合适数据清理策略和参数,磁盘问题将会导致集群节点宕机,甚至服务不可用。

public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
    ...
    public void takeSnapshot(boolean syncSnap) {
        long start = Time.currentElapsedTime();
        try {
            txnLogFactory.save(zkDb.getDataTree(), zkDb.getSessionWithTimeOuts(), syncSnap);
        } catch (IOException e) {
            LOG.error("Severe unrecoverable error, exiting", e);
            // This is a severe error that we cannot recover from,
            // so we need to exit
            ServiceUtils.requestSystemExit(ExitCode.TXNLOG_ERROR_TAKING_SNAPSHOT.getValue());
        }
            ...
    }
    ...
}

当 Server 尝试将内存中的数据写入磁盘的时候,就会产生异常,Server 进程会直接退出。

对于这些问题,ZooKeeper 官方提供一些参数,通过合理的配置参数能够有效的减缓磁盘压力,接下来深入探究一下相关参数。

  • autopu rge.snapRetainCount : (No Java system property) New in 3.4.0
  • autopurge.purgeInterval : (No Java system pro perty) New in 3.4.0

首先 ZooKeeper 官方是支持定时清理数据文件的能力的,通过 autopurge.snapRetainCount 和 autopurge.purgeInterval 指定清理的间隔和清理时需要保留的数据文件的个数,这里需要注意的是,ZooKeeper 中开启此能力需要将 autopurge.purgeInterval 设置为一个大于 0 的值,此值代表清理任务运行的间隔(单位是小时)。一般情况下,配置这两个参数开启定时清理能力之后能够很大程度减轻磁盘的容量压力。但是定时清理任务的最小间隔是 1 小时,这在一些特殊场景下无法避免磁盘爆满的问题。

当在两次磁盘的清理间隔中,有大量的数据变更请求时,会产生大量的 transaction log 文件和 snapshot 文件,由于没有达到清理的事件间隔,数据累计最终在下一次磁盘清理之前把磁盘写满。为了更好了理解其他参数,我们先探究一下 ZooKeeper 会在什么时候产生快照文件和事务日志文件。

ZooKeeper 在什么时间生成这些数据文件

通过在代码中方法引用 (ZooKeeperServer.takeSnapshot),发现在以下情况下会触发新的快照文件的生成

  • 节点启动,加载完数据文件之后
  • 集群中产生新 leader
  • SyncRequestProcessor 中达到一定条件(shouldSnapshot 方法指定)

前两种情况都是非高频的,我们看一下第三种情况,在 SyncRequestProcessor 的 run 方法中调用了 takeSnapshot 方法,在此之前调用了 shouldSnapshot 进行了判断:

private boolean shouldSnapshot() {
    int logCount = zks.getZKDatabase().getTxnCount();
    long logSize = zks.getZKDatabase().getTxnSize();
    return (logCount > (snapCount / 2 + randRoll))
        || (snapSizeInBytes > 0 && logSize > (snapSizeInBytes / 2 + randSize));
}

其中 logCount 的值是当前事务日志文件的大小以及事务日志的数量,snapCount,snapSizeInBytes 是通过 Java SystemProperty 配置的值,randRoll 是一个随机数(0 < randRoll < snapCount / 2),randSize 也是一个随机数(0 < randSize < snapSizeInBytes / 2),因此这个判断条件的逻辑可以总结为下:

当当前事务日志文件中的事务数量大于运行时产生的和 snapCount 相关的一个随机值(snapCount/2 < value < snapCount)或者当前的事务日志文件的大小大于一个运行是产生的和 snapSizeInBytes 相关的随机值(snapSizeInBytes/2 < value < snapSizeInBytes)就会进行一次 snapshot 的文件写入,并且可以从代码中看到,写入snapshot会将现在的事务日志文件刷入磁盘,并新建一个事务日志文件。

public void run() {
    if (shouldSnapshot()) {
        resetSnapshotStats();
        // 滚动事务日志文件
        zks.getZKDatabase().rollLog();
        // take a snapshot
        if (!snapThreadMutex.tryAcquire()) {
            LOG.warn("Too busy to snap, skipping");
        } else {
            new ZooKeeperThread("Snapshot Thread") {
                public void run() {
                    try {
                        zks.takeSnapshot();
                    } catch (Exception e) {
                        LOG.warn("Unexpected exception", e);
                    } finally {
                        snapThreadMutex.release();
                    }
                }
            }.start();
        }
    }
}

snapCount,snapSizeInBytes 这两个变量可以通过 ZooKeeper 的配置文件中指定。

  • snapCount : (Java system property: zookeeper.snapCount)
  • snapSizeLimitInKb : (Java system property: zookeeper.snapSizeLimitInKb)

由此可知,可以通过在配置文件中配置 snapCount 和 snapSizeLimitInKb 来控制 snapshot 文件产生的频率。

建议

通过以上分析可知,可以通过 4 个参数对 ZooKeeper 的数据文件生成和清理进行配置。

  • autopurge.snapRetainCount : (No Java system property) New in 3.4.0
  • autopurge.purgeInterval : (No Java system property) New in 3.4.0
  • snapCount : (Java system property: zookeeper.snapCount)
  • snapSizeLimitInKb : (Java system property: zookeeper.snapSizeLimitInKb)

前两个配置项指定 ZooKeeper 的定时清理策略,后两个参数配置ZooKeeper生成快照文件的频率。

根据前面分析,可以指通过将 snapCount 和 snapSizeLimitInKb 调整大可以减小 snapshot 的生成频率,但是如果设置的过大,会导致在节点重启时,加载数据缓慢,延长服务的恢复时间,增大业务风险。

autopurge.purgeInterval 最小只能指定为 1,这将清理间隔硬限制到 1 小时,针对高频写入情景无法降低风险。

MSE ZooKeeper 针对以上分析的 ZooKeeper 的磁盘问题,设置了合适的参数,并且用户可以方便更改相关参数实现业务场景适配,并且 MSE ZooKeeper 在 ZooKeeper 自身的数据清理机制外,提供额外保障手段,保障集群免受磁盘问题影响。

在这里插入图片描述

运营活动

重磅推出 MSE 专业版,更具性价比,可直接从基础版一键平滑升级到专业版!

在这里插入图片描述

点击此处 ,前往微服务引擎 MSE 官网查看更多~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/141208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在线客服系统部署配置邮箱消息通知功能 - 唯一客服(v1kf.com) -开源私有化独立部署在线客服系统源码...

为在线客服系统设置邮件通知具有以下几个好处&#xff1a; 改善客户体验&#xff1a;邮件通知可以让客户实时收到新消息或更新通知&#xff0c;这有助于提高他们对您的服务的整体体验。 提高效率&#xff1a;邮件通知可以帮助提高客服团队的效率&#xff0c;因为它们会在新消息…

非专业人士如何完成数据采集?纯干货,一文看懂

写在前面&#xff1a; 本教程能够解决大部分人的数据采集及分析需求&#xff0c;实用、简单&#xff0c;尤其适合Excel大户、办公族、业务人员&#xff0c;或者不会编程、不懂数据分析理论的技术小白…… 来不及看的可以先点赞收藏&#xff01; 01 点对点的采集&#xff1a;…

吴恩达《机器学习》——欠拟合与过拟合

欠拟合与过拟合1. 方差与偏差模型的容量、过拟合和欠拟合2. Python代码实践2.1 拟合直线2.2 拟合多项式数据集、源文件可以在Github项目中获得 链接: https://github.com/Raymond-Yang-2001/AndrewNg-Machine-Learing-Homework 1. 方差与偏差 在数学上&#xff0c;估计的偏差…

Java基础漏洞(二)

继续填补自己的知识漏洞 1.&、&&、|、||之间的区别 &是逻辑与&#xff0c;而&&则是短路与。&和&&之间的区别是&#xff0c;在短路与&&的情况下&#xff0c;两个条件当第一个条件为假时&#xff0c;则不再执行第二个条件&#xf…

java学习之类方法

目录 一、基本介绍 二、类方法的调用 三、类方法的应用实例 代码 内存分析 运行结果 四、类方法的经典使用场景 五、类方法使用细节 第一条 第二条 第三条 第四条 第五条 第六条 六、练习 第一题 考察点 分析 结果 第二题 代码 考察点 结果 第三题 类方法 …

LeetCode498. 对角线遍历

LeetCode刷题记录 文章目录&#x1f4dc;题目描述&#x1f4a1;解题思路⌨C代码&#x1f4dc;题目描述 给你一个大小为 m x n 的矩阵 mat &#xff0c;请以对角线遍历的顺序&#xff0c;用一个数组返回这个矩阵中的所有元素。 示例1 输入&#xff1a;mat [[1,2,3],[4,5,6],[…

VUE2使用浏览器缓存的方法

分两种&#xff1a;localStorage和sessionStorage&#xff0c;它两统称webStorage 注意点1&#xff1a;localStorage对象和sessionStorage对象都是window对象下的&#xff0c;且方法都是一样的&#xff0c;默认”window.”可以省略,添加可用setItem(K,V)&#xff0c;查询可用ge…

数据库|scMethBank:单细胞全基因组 DNA 甲基化图谱数据库

甲基化是DNA的一种重要化学修饰&#xff0c;可调节基因的表达和关闭&#xff0c;与癌症、衰老、老年痴呆等许多疾病密切相关&#xff0c;是表观遗传学的重要研究内容之一。测序技术的发展&#xff0c;极大促进了单细胞DNA甲基化研究。然而大量数据的不断积累&#xff0c;对单细…

《HTTP权威指南》----HTTP报文

目录 报文流 报文的组成部分 报文语法 1.起始行 2.首部 通用首部&#xff0c;既可以出现在请求报文中也可以出现在响应报文中。 请求首部&#xff0c;提供更多有关请求的信息。 响应首部&#xff0c;提供更多有关响应的信息。 实体首部&#xff0c;描述主题的长度和内…

2022年,一个技术账号的年终独白,满篇都写着2个字:真难。

2022年&#xff0c;梦想橡皮擦这个账号经历了成长&#xff0c;突破&#xff0c;回归 2023年&#xff0c;适应改变 文章目录序2022年&#xff0c;梦想橡皮擦账号整体汇总原创博客KPI计划与完成总排名KPI计划与完成2022年&#xff0c;橡皮擦获得的荣誉2022年&#xff0c;做技术博…

日志收集系统架构

背景 应用服务器多&#xff0c;日志文件被分散在各个应用服务器上&#xff0c;需要依次登录每台设备才能查看日志&#xff0c;效率低下&#xff0c;且不利于服务器安全管控&#xff0c;加大生产服务器的风险&#xff1b;日志文件不统一&#xff0c;各项目日志没有统一的规范&a…

Python Django教程之实现天气应用程序

基本设置 将目录更改为天气 cd weather启动服务器 python manage.py runserver要检查服务器是否正在运行&#xff0c;请转到 Web 浏览器并输入为 URL。现在&#xff0c;您可以通过按以下命令停止服务器http://127.0.0.1:8000/ ctrl-c 实现 python manage.py startapp main…

Vehicle Speed Forecasting Based On GCN-LSTM Combined Model

GCN-LSTM模型预测道路交通车辆速度 Vehicle Speed Forecasting Based On GCN-LSTM Combined Model Summary This research offers a multistep traffic flow forecasting framework relying on interest spatial-temporal-graph neural network-long short-term memory neura…

【阅读】《MYSQL技术内幕:innodb》索引

概念 索引的类型 聚集索引&#xff1a;叶子节点包含行记录的全部数据辅助索引&#xff1a;叶子节点不包含行记录的全部数据&#xff0c;除了键值以外&#xff0c;还包含指向索引行的书签。 堆表和索引组织表 堆表 无论是主键索引还是普通索引都是辅助索引。数据是按照插入…

​力扣解法汇总2042. 检查句子中的数字是否递增

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣 描述&#xff1a; 句子是由若干 token 组成的一个列表&#xff0c;token 间用 单个 空格分隔&…

微信小程序实战十五:Https服务搭建及Nginx配置

文章目录 1.最终效果预览2.后端jar包部署及启动3.前端管理系统部署4.Nginx的配置5.https证书申请6.小程序后台中配置子域名这篇文章重点介绍下微信小程序正式版上线前https服务的搭建及配置过程,之前整个流程都操作过,时隔一年再次从零开始操作有些地方的印象已经模糊了,好记…

Java Swing五子棋项目

一、项目简介 本项目为Java Swing五子棋项目&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse 确保可…

ArcGIS基础实验操作100例--实验50以栅格分区裁剪面要素

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验50 以栅格分区裁剪面要素 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff0…

Vulkan PBR与IBL实践

对我来说&#xff0c;每天能过得心情舒畅&#xff0c;有酒喝有美味佳肴吃&#xff0c;必要时工作一会儿&#xff0c;晚上睡得舒舒服服&#xff0c;就行了。 ——迪希亚 序 说实话我已经记不清上一篇文章是什么时候的事情了&#xff0c;感觉得有好几个月了&#xff0c;但其实我…

【Linux】【信号】

文章目录一、信号是什么1.生活中的信号2.什么是Linux信号3.信号处理的常见方式4.Linux当中的信号二、信号的产生1.signal函数2.核心转储3.验证进程等待中的core dump标记位三、信号的系统调用接口1.kill2.raise3.abort四、由软件条件产生信号alarm五、硬件异常产生信号1.除零异…