golang使用zookeeper进行CURD

 更新时间:2025年11月21日 09:49:27   作者:蔡蔡开始内卷  
本文介绍Zookeeper的基本概念及其在Golang中的实现方法,包括连接建立、节点创建与查询、节点存在性的检查、节点删除及内容修改等,具有一定的参考价值,感兴趣的可以了解一下

一、Zookeeper入门

1.1. Zookeeper简介

Zookeeper是一个分布式数据库(程序协调服务),Hadoop子项目;以树状方式维护节点方数据的增、删、改、查;通过监听可以获取相应消息事件;
节点类型:

  • 持久节点:一直存储在服务器上(0)
  • 临时节点:会话失效、节点自动清理(FlagEphemeral)
  • 顺序节点:节点创建时自动分配序列号(FlagSequence)

二.启动zookeeper

三.核心包

go-zookeeper

go get github.com/samuel/go-zookeeper/zk
文档地址: http://godoc.org/github.com/samuel/go-zookeeper/zk

四.Golang实现Zookeeper核心功能

4.1 建立连接

func GetConnect(zkList []string) (conn *zk.Conn) {
	// 创建监听的option,用于初始化zk
	conn, _, err := zk.Connect(zkList, 10*time.Second)
	if err != nil {
		fmt.Println(err)
	}
	return
}

4.2创建节点

func Create(conn *zk.Conn, path string, data []byte, flags int32, acl int32) (val string, err error) {
	//flags有4种取值:
	//0:永久,除非手动删除
	//zk.FlagEphemeral = 1:短暂,session断开则改节点也被删除
	//zk.FlagSequence  = 2:会自动在节点后面添加序号
	//3:Ephemeral和Sequence,即,短暂且自动添加序号
	// 获取访问控制权限
	var acls []zk.ACL
	if acl == 0 {
		/**
		PermRead = 1 << iota   1
		PermWrite              2
		PermCreate             4
		PermDelete             8
		PermAdmin             16
		PermAll = 0x1f        31
		*/
		acls = zk.WorldACL(zk.PermAll)
	} else {
		acls = zk.WorldACL(acl)
	}

	val, err = conn.Create(path, data, flags, acls)
	return
}

var (
	zkList = []string{"127.0.0.1:2181"}
	path   = "/root"
)

func TestCreate(t *testing.T) {
	conn := GetConnect(zkList)

	defer conn.Close()
	//创建节点
	val, err := Create(conn, path, []byte("root value"), 0, 31)
	if err != nil {
		fmt.Printf("创建失败: %v\n", err)
		return
	}
	fmt.Printf("创建: %s 成功", val)
}

4.3查询节点

// 查
func Get(conn *zk.Conn, path string) (dataStr string, stat *zk.Stat, err error) {
	data, stat, err := conn.Get(path)
	if err != nil {
		return "", nil, err
	}
	return string(data), stat, err
}

func TestGet(t *testing.T) {
	conn := GetConnect(zkList)

	defer conn.Close()
	//查询节点
	val, _, err := Get(conn, path)
	if err != nil {
		fmt.Printf("查询%s失败, err: %v\n", path, err)
		return
	}
	fmt.Printf("%s 的值为 %s\n", path, val)
}

4.4 节点是否存在

func Exists(conn *zk.Conn, path string) (exist bool, err error) {
	exist, _, err = conn.Exists(path)
	return
}

func TestExist(t *testing.T) {
	conn := GetConnect(zkList)

	defer conn.Close()
	//是否存在
	val, err := Exists(conn, path)
	if err != nil {
		fmt.Printf("查询%s失败, err: %v\n", path, err)
		return
	}
	if val {
		fmt.Printf("%s 存在\n", path)
	} else {
		fmt.Printf("%s 不存在\n", path)
	}
}

4.5删除节点

//删除 cas支持
func Del(conn *zk.Conn, path string) (err error) {
	_, sate, _ := Get(conn, path)
	fmt.Println(sate)
	err = conn.Delete(path, sate.Version)
	return err
}

func TestDel(t *testing.T) {
	conn := GetConnect(zkList)

	defer conn.Close()
	// 删除
	err := Del(conn, path)
	if err != nil {
		fmt.Printf("数据删除失败: %v\n", err)
		return
	}
	fmt.Println("数据删除成功")
}

4.6 修改节点内容

// 改 CAS支持
// 可以通过此种方式保证原子性
func Modify(conn *zk.Conn, path string, newData []byte) (sate *zk.Stat, err error) {
	_, sate, _ = conn.Get(path)
	fmt.Println(sate)
	sate, err = conn.Set(path, newData, sate.Version)
	return
}


func TestModify(t *testing.T) {
	conn := GetConnect(zkList)

	defer conn.Close()
	newData := []byte("hello zookeeper")
	stat, err := Modify(conn, path, newData)
	if err != nil {
		fmt.Printf("数据修改失败: %v\n", err)
		return
	}
	fmt.Printf("数据修改成功,stat %v\n", stat)
}

4.7获取目录信息

func Children(conn *zk.Conn, path string) (data []string, err error) {
	data, _, err = conn.Children(path)
	return
}

func TestChildren(t *testing.T) {
	conn := GetConnect(zkList)

	defer conn.Close()
	data, err := Children(conn, "/")
	if err != nil {
		fmt.Printf("获取数据失败: %v\n", err)
		return
	}
	fmt.Printf("获取数据成功,data %v\n", data)
}

五.watch

func callback(event zk.Event) {
    fmt.Println(">>>>>>>>>>>>>>>>>>>")
    fmt.Println("path:", event.Path)
    fmt.Println("type:", event.Type.String())
    fmt.Println("state:", event.State.String())
    fmt.Println("<<<<<<<<<<<<<<<<<<<")
}
 
func ZKOperateWatchTest() {
    fmt.Printf("ZKOperateWatchTest\n")
 
    option := zk.WithEventCallback(callback)
    var hosts = []string{"localhost:2181"}
    conn, _, err := zk.Connect(hosts, time.Second*5, option)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer conn.Close()
 
    var path1 = "/zk_test_go1"
    var data1 = []byte("zk_test_go1_data1")
    exist, s, _, err := conn.ExistsW(path1)
    if err != nil {
        fmt.Println(err)
        return
    }
 
    fmt.Printf("path[%s] exist[%t]\n", path1, exist)
    fmt.Printf("state:\n")
    fmt.Printf("%s\n", ZkStateStringFormat(s))
 
    // try create
    var acls = zk.WorldACL(zk.PermAll)
    p, err_create := conn.Create(path1, data1, zk.FlagEphemeral, acls)
    if err_create != nil {
        fmt.Println(err_create)
        return
    }
    fmt.Printf("created path[%s]\n", p)
 
    time.Sleep(time.Second * 2)
 
    exist, s, _, err = conn.ExistsW(path1)
    if err != nil {
        fmt.Println(err)
        return
    }
 
    fmt.Printf("path[%s] exist[%t] after create\n", path1, exist)
    fmt.Printf("state:\n")
    fmt.Printf("%s\n", ZkStateStringFormat(s))
 
    // delete
    conn.Delete(path1, s.Version)
 
    exist, s, _, err = conn.ExistsW(path1)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("path[%s] exist[%t] after delete\n", path1, exist)
    fmt.Printf("state:\n")
    fmt.Printf("%s\n", ZkStateStringFormat(s))
}

不止会打印watch监听的节点信息,还有打印session会话的状态

到此这篇关于golang使用zookeeper进行CURD的文章就介绍到这了,更多相关golang zookeeper进行CURD内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • go的strings用法小结

    go的strings用法小结

    strings 是 Go 语言标准库中提供的一个包,用于处理字符串相关的操作,本文主要介绍了go的strings用法小结,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • Golang多线程刷票的实现代码

    Golang多线程刷票的实现代码

    这篇文章主要介绍了Golang多线程刷票的相关资料,这里实现刷票的功能,对于投票,刷票的很方便,并附实现代码,需要的朋友可以参考下
    2017-07-07
  • Go语言结构体定义和使用方法

    Go语言结构体定义和使用方法

    这篇文章主要介绍了Go语言结构体定义和使用方法,以实例形式分析了Go语言中结构体的定义和使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • golang限流库两个大bug(半年之久无人提起)

    golang限流库两个大bug(半年之久无人提起)

    最近我的同事在使用uber-go/ratelimit[1]这个限流库的时候,遇到了两个大 bug,这两个 bug 都是在这个库的最新版本(v0.3.0)中存在的,而这个版本从 7 月初发布都已经过半年了,都没人提 bug,难道大家都没遇到过么
    2023-12-12
  • 从源码深入理解golang RWMutex读写锁操作

    从源码深入理解golang RWMutex读写锁操作

    这篇文章主要介绍了从源码深入理解golang RWMutex读写锁操作,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • Golang RSA生成密钥、加密、解密、签名与验签的实现

    Golang RSA生成密钥、加密、解密、签名与验签的实现

    RSA 是最常用的非对称加密算法,本文主要介绍了Golang RSA生成密钥、加密、解密、签名与验签的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • golang使用通道时需要注意的一些问题

    golang使用通道时需要注意的一些问题

    本文主要介绍了golang使用通道时需要注意的一些问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • golang实现通过smtp发送电子邮件的方法

    golang实现通过smtp发送电子邮件的方法

    这篇文章主要介绍了golang实现通过smtp发送电子邮件的方法,实例分析了Go语言基于SMTP协议发送邮件的相关技巧,需要的朋友可以参考下
    2016-07-07
  • go install和go get的区别实例详解

    go install和go get的区别实例详解

    go install是Golang用来编译和安装自定义package的工具,下面这篇文章主要给大家介绍了关于go install和go get区别的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • Go输入与输出格式化案例详解

    Go输入与输出格式化案例详解

    Go语言的输入与输出格式化功能非常强大,通过 fmt 包和 bufio 包,可以满足各种输入输出需求,本文给大家介绍Go输入与输出格式化案例,感兴趣的朋友一起看看吧
    2025-10-10

最新评论