GoBeansDB 全解析

目录

写在最前:

1、豆瓣为什么要用 K/V 数据库❓

2、那么多优秀的 K/V 数据库系统,豆瓣为什么要自己重新实现一套 K/V 存储❓

3、为什么要用 Go 重新实现 BeansDB(BeansDB 是用 C 来实现的)❓

4、分布式数据库数据一致性原理说明与实现

5、与 BeansDB 关系

一、GoBeansDB 架构设计

二、GoBeansDB 安装部署

1、安装 Go(检查是否需要安装)

2、安装/升级 Git(检查是否需要安装)

3、安装 GoBeansDB

4、libmc(a high performance python/go mc client)

    1)小谈 GoBeansDB 高性能 Python 客户端

    2)Python3 BeansDB / GoBeansDB 连接 - libmc 驱动模块

5、GoBeansproxy(routing to gobeansdb cluster with three copy)

6、BeansDB Admin(webUI, sync ...)

三、GoBeansDB 配置搭建

1、GoBeansDB配置

2、GoBeansproxy配置

四、GoBeansDB 拓展问题

1、分桶数问题

2、GoBeansproxy 之 sharding 问题

五、supervise 守护 GoBeansDB 服务持续运行

1、supervise 安装

2、supervisor 使用

1)supervisor 管理 GoBeansDB ,当服务进程挂掉之后自动重启

2)supervisor 管理 GoBeansproxy,当服务进程挂掉之后自动重启

六、Python3 实现 BeansDB 与 GoBeansDB 间双向数据迁移

七、Python3 采集 GoBeansproxy 日志路由数据(SET/DELETE)存储到 MySQL

八、Python3 实现 GoBeansDB 集群节点变更以及固定副本平衡


写在最前:

1、豆瓣为什么要用 K/V 数据库❓

  • 首先是因为数据大,而且数据是非结构化数据,像豆瓣日记,就是一批很长的字符串。
  • 其次是非常多的随机读。
  • 有时候会有大量的写操作。
  • 不需要外键什么的。

通过上面四点可以排除掉类似 MySQL 这种传统的关系型数据库。

2、那么多优秀的 K/V 数据库系统,豆瓣为什么要自己重新实现一套 K/V 存储❓

  • 读写都需要比较低的 latency。
  • 数据量非常大,所以数据要写在磁盘上,数据库需要能够容纳比内存大的多的数据。
  • 高可用,单点故障不影响系统正常运行。
  • 高吞吐,尤其是针对写操作。
  • 能够快速回复有问题的节点。

通过这五点也可以排除掉 MongoDB 与 levelDB。

3、为什么要用 Go 重新实现 BeansDB(BeansDB 是用 C 来实现的)❓

  • 一个很重要的原因是 Go 的代码相比与 C 更容易维护。对一个工程师而言,Go 的学习成本比 C 要低很多。
        1. 用 Go 可以比较快速的写出健壮的系统,而用 C 来写的话,则需要一定的经验积累。
        2. Go 提供了可用的测试框架,写测试相对于 C/C++ 要方便
        3. Go 标准库里面提供了方便的性能分析工具,用 C 也有类似的工具,但是做不到开箱即用
  • 还有 Go 的标准库也足够完善,不需要用 C 来重复造轮子。
  • Go 的执行效率虽然比 C 差,但是 BeansDB 的瓶颈是 IOPS,所以 Go 的执行效率并不会成为瓶颈。

4、分布式数据库数据一致性原理说明与实现

5、与 BeansDB 关系

  • 兼容
    • 数据文件格式不变
    • 仍使用 mc 协议("@" "?" 开头的特殊 key 用法略不同)
    • htree 的核心设计不变
  • 改进
    • go 实现,更稳定,方便配置和维护(http api等)
    • 内存开销变小
    • hint 文件格式和后缀变了
    • 同一个节点不同数据文件不在混部署,以避免坏一个损失整个点数据

一、GoBeansDB 架构设计

二、GoBeansDB 安装部署

1、安装 Go(检查是否需要安装)

GoBeansDB use go mod manage dependencies, please make sure your Go version >= 1.11.0 first.

安装包下载地址为:https://golang.org/dl/

如果打不开可以使用这个地址:https://golang.google.cn/dl/

1)将下载的二进制包解压至 /usr/local目录

# cd /data/soft/
# tar -zxvf go1.12.7.linux-amd64.tar.gz -C /usr/local/

2)添加环境变量

# vim /etc/profile 
export GOROOT=/usr/local/go
export GOPATH=/home/work/go
export PATH=$PATH:/usr/local/go/bin:
  
# source /etc/profile
# go version
go version go1.12.7 linux/amd64

2、安装/升级 Git(检查是否需要安装)

Git 是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理,是目前使用范围最广的版本管理工具。

1)yum 安装

# yum install git -y
# Git 默认安装在 /usr/libexec/git-core 目录下,可输入指令,查看安装信息

存在问题:使用 yum 安装确实简单方便,但 yum 存在一个问题就是安装的版本不好控制。

2)下载最新的源码编译安装

GitHub 的 Git 版本发布界面下载地址:https://github.com/git/git/releases

# 压缩包解压
# tar -zxvf git-2.11.0.tar.gz
  
# 安装编译源码所需要的依赖
# yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker -y
  
 
# 安装依赖时,yum 自动安装了 Git,需要卸载旧版本 Git,需要清除 yum 安装的老版本
# yum remove git -y
 
 
# 进入解压后的文件夹,执行编译安装(耐心等待编译)
# make prefix=/usr/local/git all
 
# 安装 Git 至 /usr/local/git 路径
# make prefix=/usr/local/git install
  
# 打开环境变量配置文件(vim /etc/profile),添加环境变量
export PATH=$PATH:/usr/local/git/bin
  
# 查看安装版本
# git --version
git version 2.11.0

3、安装 GoBeansDB

# su - work
$ git clone http://github.com/douban/gobeansdb.git
Cloning into 'gobeansdb'...
fatal: unable to access 'https://github.com/douban/gobeansdb.git/': SSL connect error

1)OpenSSL 安装(检查是否需要安装)

OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

下载:https://www.openssl.org/source/,本例使用版本:openssl-1.0.2o.tar.gz

# 解压
# tar -zxvf openssl-1.0.2o.tar.gz
  
# 检查zlib是否已经安装,如果没有安装就先安装
# whereis zlib
# yum install zlib -y
  
# 安装 openssl 到 /usr/local/openssl 目录
# ./config shared zlib  --prefix=/usr/local/openssl && make && make install
  
# 进入 /usr/local 目录执行以下命令
# cd /usr/local/
# ln -s openssl ssl
  
# 添加到系统配置
# vim /etc/ld.so.conf(添加一行下面内容)
    /usr/local/openssl/lib
# ldconfig -v
  
# mv /usr/bin/openssl /usr/bin/openssl.back
# cp /usr/local/openssl/bin/openssl /usr/bin/openssl
# openssl version
OpenSSL 1.0.2o  27 Mar 2018
  
# yum install nss -y

2)安装 GoBeansDB

# su - work
$ git clone http://github.com/douban/gobeansdb.git
Cloning into 'gobeansdb'...
remote: Enumerating objects: 84, done.
remote: Counting objects: 100% (84/84), done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 3669 (delta 55), reused 64 (delta 48), pack-reused 3585
Receiving objects: 100% (3669/3669), 3.27 MiB | 203.00 KiB/s, done.
Resolving deltas: 100% (2633/2633), done.
  
$ cd gobeansdb/
$ make
GO111MODULE=on go mod vendor
go: finding github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
go: finding github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
go: finding gopkg.in/yaml.v2 v2.2.1
go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
go: downloading gopkg.in/yaml.v2 v2.2.1
go: downloading github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
go: downloading github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
go: extracting github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
go: extracting github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
go: extracting gopkg.in/yaml.v2 v2.2.1
go install ./

3)安装过程中可能出现的错误

在项目中使用 golang Modules 却无法下载还报了以下错误:

$ make
GO111MODULE=on go mod vendor
go: finding github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
go: finding github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
go: finding gopkg.in/yaml.v2 v2.2.1
go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
go: golang.org/x/tools@v0.0.0-20191011211836-4c025a95b26e: unrecognized import path "golang.org/x/tools" (https fetch: Get https://golang.org/x/tools?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
go: error loading module requirements
make: *** [install] Error 1

原因也许是知道的!局域网没办法。

解决方案:Go 1.11 版本开始,官方支持了 go module 包依赖管理工具。其实还新增了 GOPROXY 环境变量。如果设置了该变量,下载源代码时将会通过这个环境变量设置的代理地址,而不再是以前的直接从代码库下载。https://goproxy.io/ 这个开源项目帮我们实现好了我们想要的。该项目允许开发者一键构建自己的 GOPROXY 代理服务。同时,也提供了公用的代理服务 https://goproxy.io,我们只需设置该环境变量即可正常下载被墙的源码包了:

$ export GO111MODULE=on
$ export GOPROXY=https://goproxy.io
$ make
GO111MODULE=on go mod vendor
go: finding gopkg.in/yaml.v2 v2.2.1
go: finding github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
go: finding github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
go: finding golang.org/x/tools v0.0.0-20191011211836-4c025a95b26e
go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
go: finding golang.org/x/sync v0.0.0-20190423024810-112230192c58
go: finding golang.org/x/net v0.0.0-20190620200207-3b0461eec859
go: finding golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
go: finding golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
go: finding golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
go: finding golang.org/x/text v0.3.0
go: downloading gopkg.in/yaml.v2 v2.2.1
go: downloading github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
go: downloading github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
go: extracting gopkg.in/yaml.v2 v2.2.1
go: extracting github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
go: extracting github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
go install ./

4)test

$ make test
go version
go version go1.12.7 linux/amd64
go test github.com/douban/gobeansdb/memcache
ok      github.com/douban/gobeansdb/memcache    0.008s
go test github.com/douban/gobeansdb/loghub
ok      github.com/douban/gobeansdb/loghub  0.004s
go test github.com/douban/gobeansdb/cmem
ok      github.com/douban/gobeansdb/cmem    0.007s
go test github.com/douban/gobeansdb/quicklz
ok      github.com/douban/gobeansdb/quicklz 0.006s
ulimit -n 1024; go test github.com/douban/gobeansdb/store
ok      github.com/douban/gobeansdb/store   218.714s
  
$ make pytest

5)run

$ /home/work/go/bin/gobeansdb -h
Usage of /home/work/go/bin/gobeansdb:
  -buildhint string
        a data file OR a bucket dir
  -confdir string
        path of server config dir
  -dumpconf
        print configuration
  -version
        print version of gobeansdb
  
$ /home/work/go/bin/gobeansdb -version
gobeansdb version 2.1.0.18

4、libmc(a high performance python/go mc client)

$ pip install libmc

    1)小谈 GoBeansDB 高性能 Python 客户端

    2)Python3 BeansDB / GoBeansDB 连接 - libmc 驱动模块

5、GoBeansproxy(routing to gobeansdb cluster with three copy)

1)lease install vgo first. Supported Go version: 1.10.1+

// 在 ${GOPATH}/src 下的目录层次 src/golang.org/x (没有哪个层次就创建哪个层次,因为 vgo 的包名是 golang.org/x/vgo ),然后在x目录下使用 git 克隆 vgo 仓库 git clone github.com/golang/vgo,进入 vgo 目录运行命令 go build main.go,最后将生成的 vgo 二进制文件复制到你的环境变量路径里(注意 vgo 二进制文件的命名:Windows 系统是 vgo.exe,Mac 或 Linux 是无后缀的 vgo)。
$ cd ${GOPATH}
$ mkdir -pv ${GOPATH}/src/golang.org/x
$ cd ${GOPATH}/src/golang.org/x
$ go get -u golang.org/x/vgo
package golang.org/x/vgo: unrecognized import path "golang.org/x/vgo" (https fetch: Get https://golang.org/x/vgo?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
  
$ git clone https://github.com/golang/vgo.git
Cloning into 'vgo'...
remote: Enumerating objects: 3348, done.
remote: Total 3348 (delta 0), reused 0 (delta 0), pack-reused 3348
Receiving objects: 100% (3348/3348), 3.60 MiB | 167.00 KiB/s, done.
Resolving deltas: 100% (1674/1674), done.
 
// 进入 vgo 目录
$ cd vgo/ 
$ go build main.go
// 最后将生成的 vgo 二进制文件复制到你的环境变量路径里(注意 vgo 二进制文件的命名:Windows系统是 vgo.exe,Mac 或 Linux 是无后缀的 vgo)

2)安装 GoBeansproxy

# su - work
$ git clone http://github.com/douban/gobeansproxy.git
Cloning into 'gobeansproxy'...
remote: Enumerating objects: 1078, done.
remote: Total 1078 (delta 0), reused 0 (delta 0), pack-reused 1078
Receiving objects: 100% (1078/1078), 392.09 KiB | 242.00 KiB/s, done.
Resolving deltas: 100% (504/504), done.
  
$ cd gobeansproxy
$ make
CC=unknown go install ./
# runtime/cgo
exec: "unknown": executable file not found in $PATH
make: *** [install] Error 2
$ ag 'unknown'
Makefile
13:    COMPILER = unknown
$ echo $(shell $(CC) --help | head -n 1)
-bash: CC: command not found
-bash: shell: command not found
# 修改 Makefile 文件添加一行(CC=gcc)
$ vim Makefile
# FIXME: When this issue is done(https://github.com/golang/go/issues/23965#issuecomment-409232583)
# Determine the compiler and version
CC=gcc
COMPILER_HELP := $(shell $(CC) --help | head -n 1)
  
$ make
CC=gcc go install ./
  
$ /home/work/go/bin/gobeansproxy -h
Usage of /home/work/go/bin/gobeansproxy:
  -confdir string
        path of proxy config dir
  -dumpconf
        print configuration
  -version
        print vresion of beansproxy
$ /home/work/go/bin/gobeansproxy -version
gobeansproxy version v1.0.2

6、BeansDB Admin(webUI, sync ...)

# root 用户
# pip install git+https://github.com/douban/beansdbadmin.git@master#egg=beansdbadmin
# su - work
$ git clone https://github.com/douban/beansdbadmin.git
Cloning into 'beansdbadmin'...
remote: Enumerating objects: 592, done.
remote: Total 592 (delta 0), reused 0 (delta 0), pack-reused 592
Receiving objects: 100% (592/592), 288.92 KiB | 165.00 KiB/s, done.
Resolving deltas: 100% (356/356), done.
  
$ cd beansdbadmin
$ python setup.py build_ext --inplace
running build_ext
building 'beansdbadmin.core.fnv1a' extension
creating build
creating build/temp.linux-x86_64-2.7
creating build/temp.linux-x86_64-2.7/beansdbadmin
creating build/temp.linux-x86_64-2.7/beansdbadmin/core
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/local/include/python2.7 -c beansdbadmin/core/fnv1a.c -o build/temp.linux-x86_64-2.7/beansdbadmin/core/fnv1a.o
beansdbadmin/core/fnv1a.c: In function ‘get_hash_bugfree’:
beansdbadmin/core/fnv1a.c:72: warning: pointer targets in passing argument 1 of ‘hash_fnv1a_bugfree’ differ in signedness
beansdbadmin/core/fnv1a.c:22: note: expected ‘const unsigned char *’ but argument is of type ‘char *’
beansdbadmin/core/fnv1a.c: At top level:
beansdbadmin/core/fnv1a.c:127: warning: function declaration isn’t a prototype
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/beansdbadmin
creating build/lib.linux-x86_64-2.7/beansdbadmin/core
gcc -pthread -shared build/temp.linux-x86_64-2.7/beansdbadmin/core/fnv1a.o -o build/lib.linux-x86_64-2.7/beansdbadmin/core/fnv1a.so
copying build/lib.linux-x86_64-2.7/beansdbadmin/core/fnv1a.so -> beansdbadmin/core
  
$ ll /usr/local/bin/beansdb*
-rwxr-xr-x 1 root root 106253 Sep 17  2013 /usr/local/bin/beansdb
-rwxr-xr-x 1 root root    420 Aug 21 15:23 /usr/local/bin/beansdbadmin-server
-rwxr-xr-x 1 root root    402 Aug 21 15:23 /usr/local/bin/beansdb-gc
-rwxr-xr-x 1 root root    416 Aug 21 15:23 /usr/local/bin/beansdb-logreport
  
$ beansdbadmin-server --cluster [db] --port [port]

三、GoBeansDB 配置搭建

1、GoBeansDB配置

/home/work/service/gobeansdb_cluster7980
├── beansdb
├── conf
│   ├── global.yaml
│   ├── local.yaml
│   └── route.yaml
├── gobeansdb
├── local
├── log
│   ├── access.log
│   ├── gobeansdb_analysis.log
│   └── gobeansdb.log
└── test

2、GoBeansproxy配置

/home/work/service/gobeansproxy
├── conf
│   ├── proxy.yaml
│   └── route.yaml
├── gobeansproxy
├── log
│   ├── proxy-access.log
│   └── proxy-error.log
└── test

proxy.yaml 提供的 NWR 是 N=3, R=1, W=2。读时只要从一个节点读到数据就返回,写时需要写到两个节点就表示写成功。

四、GoBeansDB 拓展问题

/home/work/
├── beansdbadmin
├── go
│   ├── bin
│   │   ├── gobeansdb
│   │   └── gobeansproxy
│   └── pkg
├── gobeansdb
│   ├── cmem
│   ├── conf
│   ├── config
│   │   ├── config.go
│   │   ├── route.go
│   ├── gobeansdb
│   ├── go.mod
│   ├── go.sum
│   ├── LICENSE
│   ├── loghub
│   ├── main.go
│   ├── Makefile
│   ├── memcache
│   ├── quicklz
│   ├── README.md
│   ├── store
│   │   ├── bucket.go
│   │   ├── config.go
│   ├── tests
│   ├── utils
│   └── vendor
├── gobeansproxy
│   ├── conf
│   ├── config
│   │   ├── config.go
│   │   └── default.go
│   ├── dstore
│   │   ├── bucket.go
│   │   ├── consistent.go
│   │   ├── ringqueue.go
│   │   ├── scheduler.go
│   │   ├── store.go
│   ├── gobeansproxy
│   ├── go.mod
│   ├── go.sum
│   ├── LICENSE
│   ├── main.go
│   ├── Makefile
│   ├── misc
│   ├── README.md
│   ├── templates
│   ├── tests
│   └── utils
└── service
    ├── gobeansdb_cluster7980
    │   ├── beansdb
    │   ├── conf
    │   │   ├── global.yaml
    │   │   ├── local.yaml
    │   │   └── route.yaml
    │   ├── gobeansdb
    │   ├── local
    │   ├── log
    │   │   ├── access.log
    │   │   ├── gobeansdb_analysis.log
    │   │   └── gobeansdb.log
    │   └── test
    ├── gobeansdb_cluster7981
    │   ├── beansdb
    │   ├── conf
    │   │   ├── global.yaml
    │   │   ├── local.yaml
    │   │   └── route.yaml
    │   ├── gobeansdb
    │   ├── local
    │   ├── log
    │   │   ├── access.log
    │   │   ├── gobeansdb_analysis.log
    │   │   └── gobeansdb.log
    │   └── test
    ├── gobeansdb_cluster7982
    │   ├── beansdb
    │   ├── conf
    │   │   ├── global.yaml
    │   │   ├── local.yaml
    │   │   └── route.yaml
    │   ├── gobeansdb
    │   ├── local
    │   ├── log
    │   │   ├── access.log
    │   │   ├── gobeansdb_analysis.log
    │   │   └── gobeansdb.log
    │   └── test
    ├── gobeansdb_cluster7983
    │   ├── conf
    │   │   ├── global.yaml
    │   │   ├── local.yaml
    │   │   └── route.yaml
    │   ├── gobeansdb
    │   ├── local
    │   ├── log
    │   │   ├── access.log
    │   │   ├── gobeansdb_analysis.log
    │   │   └── gobeansdb.log
    │   └── test
    ├── gobeansproxy
    │   ├── conf
    │   │   ├── proxy.yaml
    │   │   └── route.yaml
    │   ├── gobeansproxy
    │   ├── log
    │   │   ├── proxy-access.log
    │   │   └── proxy-error.log
    │   └── test
    └── python_example
        └── gobeansdb_example.py

1、分桶数问题

问题:按照上面或官方默认安装启动后,分桶数为 16。

解决方案:修改配置 route.yaml 文件,只需修改分桶数 numbucket 参数为 256,已经 buckets 即可(具体参考 route.yaml 256 分区配置)。

特别注意:GoBeansproxy 只允许有 3+ 节点,route.yaml 配置文件中 backup 一定要配置(配置 IP:PORT 可以不存在),/home/work/gobeansproxy/misc/gobeansdb_server.sh 文件中的端口号要和 route.yaml 的端口号一致

2、GoBeansproxy 之 sharding 问题

自动随机 sharding,只需调整 GoBeansproxy 配置文件 proxy.yaml 提供的 NWR(R ≤ N ≥ W),举个例子即 N=3, R=1, W=1。与 GoBeansproxy 的 route.yaml 配置文件中的 buckets 参数手动分配无关。

N=3, R=1, W=1

N:一份数据(或一个 key-value)最终保证有 3 副本数据一致,根据 W 的配置可能出现短时间内的数据不一致;

R:读时只要从一个节点读到数据就返回(GoBeansproxy 不记录每个 key 具体路由,而是从各个节点去查找,只要从一个节点读到数据就返回);

W:写时需要写到一个节点就表示写成功(GoBeansproxy 不记录写入 key 的具体路由)。

新增或删减节点只需更新 route.yaml 配置文件,重启 GoBeansproxy 即可。因为 GoBeansproxy 不记录路由,所以只要保证集群中至少有一份数据(或一个 key-value)即可正常使用。如果加入的节点本身就有数据,通过集群也可正常使用访问等操作。

五、supervise 守护 GoBeansDB 服务持续运行

在项目中总会存在一些意想不到的的问题,导致任务出错中断停止,我们需要去监控任务的执行状态,并当进程执行失败的时候进行重启。

Daemontools 是一个包含了很多管理 Unix 服务的工具的软件包。其中最核心的工具是 supervise,它的功能是监控一个指定的服务,当该服务进程消亡,则重新启动该进程。

而要添加让 supervise 监控的服务非常容易,只需要添加一个被监控的服务的目录,在该目录中添加启动服务器的名字为 run 的脚本文件即可。

当 supervisor 被 kill,管理的项目全部死掉,重启 supervisor,管理的项目都重启。

在此处我使用 supervisor 管理 GoBeansDB 和 GoBeansproxy,当服务进程挂掉之后自动重启。

1、supervise 安装

1)获取supervise 安装包:wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz

2)新建文件夹 supervise

        $ cd /home/work/

        $ mkdir supervise

3)解压 daemontools-0.76.tar.gz 到 /home/work/service/gobeansdb_cluster7980/supervise

        # tar -zxvf daemontools-0.76.tar.gz -C /home/work/supervise

        # cd /home/work/supervise/admin/daemontools-0.76

        # ls
            package      src

4)编辑conf-cc,在conf-cc 最后加上:-include /usr/include/errno.h

$ vim src/conf-cc

gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -include /usr/include/errno.h
 
This will be used to compile .c files.

5)执行安装命令(此命令需要安装过gcc。如果没有安装gcc 需要安装 gcc )

# cd /home/work/supervise/admin/daemontools-0.76
# ./package/install
// CentOS 安装gcc 命令:yum -y install gcc gcc-c++ autoconf make
  
// 检查安装(如果出现如下所示则安装成功。)
# cat /etc/inittab
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:
 
SV:123456:respawn:/command/svscanboot

2、supervisor 使用

supervise 添加监控的服务非常容易,只需要添加一个被监控的服务的目录,在该目录中添加启动服务器的名字为 run 的脚本文件即可。

1)supervisor 管理 GoBeansDB ,当服务进程挂掉之后自动重启

$ cd /home/work/service/gobeansdb_cluster7980
$ mkdir supervise
// 在 supervise 目录下编写脚本 run(注意:名字必须为 run。注意 run 脚本里不能后台启动),来管理 GoBeansDB,以便 supervise 进行调用
$ cd supervise
$ vim run
  1 #!/bin/bash
  2 BASE="/home/work/service/gobeansdb_cluster7980"
  3 CONFDIR="/home/work/service/gobeansdb_cluster7980/conf"
  4 BIN="${GOPATH}/bin/gobeansdb"
  5 IP=$(/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|egrep -v "lo|inet6"|awk '{print $2}'|tr -d "addr:"|sed -n "1p")
  6 PORT=7980
  7 DATA="/home/work/service/gobeansdb_cluster7980/beansdb"
  8
  9 suffix=`date +"%Y%m%d %H:%M:%S"`
 10 echo "${suffix} restart gobeansdb " >> ${BASE}/supervise/logs/run.log
 11 ${BIN} -confdir ${CONFDIR}
  
$ chmod 755 run
// 启动
$ nohup supervise /home/work/service/gobeansdb_cluster7980/supervise/ > /dev/null 2>&1 &
  
// 检查 GoBeansDB 进程
$ ps -ef | grep gobeansdb
    work      8122  5211  0 11:11 pts/1    00:00:00 supervise /home/work/service/gobeansdb_cluster7980/supervise/
    work      8133  8123 99 11:11 pts/1    00:00:44 /home/work/go/bin/gobeansdb -confdir /home/work/service/gobeansdb_cluster7980/conf
    work      8153  5211  0 11:11 pts/1    00:00:00 grep gobeansdb
$ netstat -lntp | grep gobeansdb
    tcp        0      0 0.0.0.0:7980                0.0.0.0:*                   LISTEN      8133/gobeansdb
    tcp        0      0 0.0.0.0:7970                0.0.0.0:*                   LISTEN      8133/gobeansdb

2)supervisor 管理 GoBeansproxy,当服务进程挂掉之后自动重启

$ cd /home/work/service/gobeansproxy
$ mkdir supervise
$ cd supervise/
$ vim run
  1 #!/bin/bash
  2 BASE="/home/work/service/gobeansproxy"
  3 CONFDIR="/home/work/service/gobeansproxy/conf"
  4 BIN="${GOPATH}/bin/gobeansproxy"
  5 IP=$(/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|egrep -v "lo|inet6"|awk '{print $2}'|tr -d "addr:"|sed -n "1p")
  6 PORT=7905
  7
  8 suffix=`date +"%Y%m%d %H:%M:%S"`
  9 echo "${suffix} restart gobeansproxy " >> ${BASE}/supervise/logs/run.log
 10 ${BIN} -confdir ${CONFDIR}
  
$ chmod 755 run
// 启动
$ nohup supervise /home/work/service/gobeansproxy/supervise/ > /dev/null 2>&1 &
// 检查 GoBeansproxy 进程
$ ps -ef | grep gobeansproxy
    work      8597  8543  0 11:28 pts/3    00:00:00 supervise /home/work/service/gobeansproxy/supervise/
    work      8608  8598  5 11:28 pts/3    00:00:05 /home/work/go/bin/gobeansproxy -confdir /home/work/service/gobeansproxy/conf
    work      8832  5211  0 11:30 pts/1    00:00:00 grep gobeansproxy
$ netstat -lntp | grep gobeansproxy
    tcp        0      0 0.0.0.0:7905                0.0.0.0:*                   LISTEN      8608/gobeansproxy
    tcp        0      0 0.0.0.0:7908                0.0.0.0:*                   LISTEN      8608/gobeansproxy

六、Python3 实现 BeansDB 与 GoBeansDB 间双向数据迁移

七、Python3 采集 GoBeansproxy 日志路由数据(SET/DELETE)存储到 MySQL

八、Python3 实现 GoBeansDB 集群节点变更以及固定副本平衡

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值