ZooKeeper-备份(Backup)

作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

前面我们介绍介绍了几个常用的代理服务器,本章节我们讲来讲解Zookeeper这个中间件。

ZooKeeper作为一个分布式软件,在生产中一般都是多节点运行的,所以对于备份的需求其实并不高,但是这里还是介绍3个方法。

方法一

前面介绍ZooKeeper数据是在虽然内存里面的,但是本地会存储事务日志和快照数据,所以我们的备份其实就备份当前节点全部数据,包括快照数据和事务日志即可。

方法二

就是把新的机器作为节点加入到集群里面,加入成功以后它会自动同步所有数据,然后在把该节点加入到新的空集群里面,实际上和方法一类似。适合用于迁移。

方法三

就是把ZooKeeper里面的数据全部导出来,另存为文件。当然这个方法也适用ZooKeeper迁移,而且有些是PAAS产品,这个我们是拿不到快照文件和事务日志的。

下面的代码也是使用DeepSeek生成,只考虑递归导出了ZooKeeper的所有znode,未考虑涉及ACL的问题,并且支持导出和导入。

python 复制代码
import json
import base64
from kazoo.client import KazooClient
from kazoo.exceptions import NoNodeError, NodeExistsError
class ZKMigrator:
    def __init__(self, hosts):
        self.zk = KazooClient(hosts=hosts)
        self.zk.start()
    def close(self):
        self.zk.stop()
    def export_persistent_nodes(self, output_file):
        """导出所有持久节点数据(忽略ACL)"""
        nodes = {}
        def _walk(path):
            data, stat = self.zk.get(path)
            # 只导出持久节点 (ephemeralOwner=0 表示持久节点)
            if stat.ephemeralOwner == 0:
                # 二进制数据转 Base64 存储
                nodes[path] = {
                    "data": base64.b64encode(data).decode('utf-8')
                }
            children = self.zk.get_children(path)
            for child in children:
                _walk(f"{path}/{child}" if path != '/' else f"/{child}")
        _walk('/')
        with open(output_file, 'w') as f:
            json.dump(nodes, f, indent=2)
        print(f"导出完成,共 {len(nodes)} 个持久节点 -> {output_file}")
    def import_nodes(self, input_file, overwrite=False):
        """从文件导入节点到当前集群(忽略ACL)"""
        with open(input_file, 'r') as f:
            nodes = json.load(f)
        for path, meta in nodes.items():
            data = base64.b64decode(meta['data'])
            # 确保父路径存在
            parent = '/'.join(path.split('/')[:-1]) or '/'
            if not self.zk.exists(parent):
                self.zk.ensure_path(parent)
            try:
                self.zk.create(path, data, makepath=True)
                print(f"创建节点: {path}")
            except NodeExistsError:
                if overwrite:
                    self.zk.set(path, data)
                    print(f"覆盖节点: {path}")
                else:
                    print(f"跳过已存在节点: {path}")
        print(f"导入完成,共处理 {len(nodes)} 个节点")
if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description='ZooKeeper 数据迁移工具')
    parser.add_argument('action', choices=['export', 'import'], help='操作类型')
    parser.add_argument('-s', '--source', help='源集群地址 (逗号分隔)')
    parser.add_argument('-d', '--dest', help='目标集群地址 (逗号分隔, import 时必填)')
    parser.add_argument('-f', '--file', required=True, help='数据文件路径')
    parser.add_argument('--overwrite', action='store_true', help='覆盖已存在节点')
    args = parser.parse_args()
    if args.action == 'export':
        if not args.source:
            parser.error("导出操作需要指定源集群 (-s/--source)")
        migrator = ZKMigrator(args.source)
        migrator.export_persistent_nodes(args.file)
        migrator.close()
    elif args.action == 'import':
        if not args.dest:
            parser.error("导入操作需要指定目标集群 (-d/--dest)")
        migrator = ZKMigrator(args.dest)
        migrator.import_nodes(args.file, args.overwrite)
        migrator.close()

导出

typescript 复制代码
[root@localhost ~]# python c.py  export -s "192.168.31.140:2181" -f zk.json
导出完成,共 8 个持久节点 -> zk.json

导入

bash 复制代码
[root@localhost ~]# python3 c.py import -d 192.168.31.140:2181 -f ./zk.json 
跳过已存在节点: /
创建节点: /a
创建节点: /b
创建节点: /c
跳过已存在节点: /zookeeper
跳过已存在节点: /zookeeper/config
跳过已存在节点: /zookeeper/quota
创建节点: /e
导入完成,共处理 8 个节点

#添加该参数会覆盖已经存在的节点
#--overwritep
ython3 c.py \
import \
-d 192.168.31.140:2181 \
-f ./zk.json \
--overwrite

运维小路

一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!

关注微信公众号《运维小路》获取更多内容。

相关推荐
路溪非溪6 分钟前
关于Linux内核中头文件问题相关总结
linux
木易双人青12 分钟前
01-Docker-简介、安装与使用
运维·docker·容器
专注API从业者1 小时前
Python + 淘宝 API 开发:自动化采集商品数据的完整流程
大数据·运维·前端·数据挖掘·自动化
Lovyk2 小时前
Linux 正则表达式
linux·运维
Fireworkitte3 小时前
Ubuntu、CentOS、AlmaLinux 9.5的 rc.local实现 开机启动
linux·ubuntu·centos
sword devil9004 小时前
ubuntu常见问题汇总
linux·ubuntu
ac.char4 小时前
在CentOS系统中查询已删除但仍占用磁盘空间的文件
linux·运维·centos
中科米堆5 小时前
中科米堆CASAIM自动化三维测量设备测量汽车壳体直径尺寸
运维·自动化·汽车·视觉检测
淮北也生橘126 小时前
Linux的ALSA音频框架学习笔记
linux·笔记·学习
缘华工业智维6 小时前
CNN 在故障诊断中的应用:原理、案例与优势
大数据·运维·cnn