InfluxDB源码编译、安装、配置及主从同步实现

article/2025/10/30 23:51:02

先扯点蛋

公司有个项目要求使用InfluxDB时序数据库储存点东西。第一次听说还有这种数据库,哈哈哈,孤陋寡闻了,先从各位大佬的博客看起,慢慢学习,逐渐了解了之后在服务器上进行安装。直接使用官方包进行安装很简单,查看官方说明即可。安装之后使用才发现,开源的只支持单机版的,但是公司用不能这么low吧,怎么也要“高可用”一点,于是自己参考MySQL主从复制原理、半同步操作步骤及原理和饿了么 Influxdb 实践之路,做了InfluxDB主从系统。


客户端系统

客户端系统拓扑图
InfluxDB主从同步拓扑图

这个系统主要是用来从kafka获取数据源,经过处理之后存到InfluxDB中去,这里参考了「饿了么」那篇文章,但是我看过他们的源码,基本上搞不懂,就根据文章的描述搞了一个简陋版的东西吧,这里涉及到kafka和influxdb-java,项目源代码可以看这里。该项目启动运行参考其中的README。


InfluxDB主从同步系统

InfluxDB同步系统
InfluxDB同步系统

主从同步架构,是简陋版的MySQL主从同步。脚本读取InfluxDB的增删改操作日志,使用脚本将记录写入从机中。经过测试,运行状况良好,只要主从机不挂,同步系统可以健康运行。

同步脚本使用Python编写,项目源代码在这里。该项目启动运行参考其中的README。

为什么使用Python脚本来编写主从同步代码?

  • 主要是考虑到降低与数据库的代码耦合程度,InfluxDB源码如果出现大规模的升级改动,同步脚本只需略作修改就可以了。
  • 毕竟Python是世界上**的语言。?

InfluxDB源码修改

  • 下载源码

    在github上下载InfluxDB源码(这里使用的是我的fork地址,已经修改好的源码)。

  • 修改源码

    由于脚本需要读取InfluxDB的增删改操作日志,需要对源码中这一部分操作的日志进行修改,方便脚本解析日志。官方版的日志不记录写入操作的数据值,所以需要我们自己修改源码中对应的记录写日志的地方。

    修改文件influxdb/services/httpd/handler.go

    // 记录日志的具体方法
    func buildLogLine(l *responseLogger, r *http.Request, start time.Time, body string) string {redactPassword(r)username := parseUsername(r)host, _, err := net.SplitHostPort(r.RemoteAddr)if err != nil {host = r.RemoteAddr}if xff := r.Header["X-Forwarded-For"]; xff != nil {addrs := append(xff, host)host = strings.Join(addrs, ",")}uri := r.URL.RequestURI()referer := r.Referer()userAgent := r.UserAgent()// 新增请求中的请求路径path := r.URL.Path// 新增请求中的form值r.ParseForm()form := r.Form// 新增请求中的body的值newbody := strings.Replace(body, "\n", ";", -1)// 将日志记录变为json格式return fmt.Sprintf(`{"timeindex":%d,"host":"%s","username":"%s","method":"%s","path":"%s","uri":"%s","form":"%s","body":"%s","proto":"%s","status":"%s","size":"%s","referer":"%s","agent":"%s","reqId":"%s"}`,start.Nanosecond(),host,detect(username, "-"),r.Method,path,uri,form,newbody,r.Proto,detect(strconv.Itoa(l.Status()), "-"),strconv.Itoa(l.Size()),detect(referer, "-"),detect(userAgent, "-"),r.Header.Get("Request-Id"))
    }

    修改文件influxdb/services/httpd/handler.go其中两处调用上面修改过的函数buildLogLine的地方

    func (h *Handler) logging(inner http.Handler, name string) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {start := time.Now()l := &responseLogger{w: w}inner.ServeHTTP(l, r)// 增加请求中的bodyh.CLFLogger.Println(buildLogLine(l, r, start, h.body))// Log server errors.if l.Status()/100 == 5 {errStr := l.Header().Get("X-InfluxDB-Error")if errStr != "" {h.Logger.Error(fmt.Sprintf("[%d] - %q", l.Status(), errStr))}}})
    }
    func (h *Handler) recovery(inner http.Handler, name string) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {start := time.Now()l := &responseLogger{w: w}defer func() {if err := recover(); err != nil {// 增加请求中的bodylogLine := buildLogLine(l, r, start, h.body)logLine = fmt.Sprintf("%s [panic:%s] %s", logLine, err, debug.Stack())h.CLFLogger.Println(logLine)http.Error(w, http.StatusText(http.StatusInternalServerError), 500)atomic.AddInt64(&h.stats.RecoveredPanics, 1) // Capture the panic in _internal stats.if willCrash {h.CLFLogger.Println("\n\n=====\nAll goroutines now follow:")buf := debug.Stack()h.CLFLogger.Printf("%s\n", buf)os.Exit(1) // If we panic then the Go server will recover.}}}()inner.ServeHTTP(l, r)})
    }

    到此InfluxDB源码修改完成。

    为什么要在func buildLogLine(l *responseLogger, r *http.Request, start time.Time, body string) string方法上增加一个字段body,而body明明是从h *Handler中获取的,而函数buildLogLine中明明是有r *http.Request的?

    因为经过测试,在func buildLogLine中从r *http.Request里面实际上取不到body的值,我没有深入研究过这段代码,确实不懂为什么会这样。所以才从上层将body的值直接传入这个方法中。

编译源码和运行

使用源码构建时序数据库主从同步系统

系统要求

Linux 64位系统即可。

依赖环境

本系统使用InfluxDB v1.5.2,所以需要Go 1.9.2或者以上的版本。

InfluxDB使用Dep管理依赖包,需要安装dep。

主从同步脚本使用Python 2.7开发。

需要从Github上拉取源码,环境中需要安装git

安装InfluxDB

新建目录$YOUR_PATH/gocodez/src$YOUR_PATH/gocodez/src$YOUR_PATH为自定义目录:

mkdir -p $YOUR_PATH/gocodez/src
mkdir -p $YOUR_PATH/gocodez/bin

将源码下载解压到目录$YOUR_PATH/gocodez/src中:

cd $YOUR_PATH/gocodez/src/
git clone https://github.com/callELPSYCONGROO/influxdb.git

将目录$YOUR_PATH/设置为GOPATH

export GOPATH=$YOUR_PATH/

进入目录中:

cd $YOUR_PATH/gocodez/src/influxdb

如果正确安装了dep,这使用这个命令安装依赖:

dep ensure

安装依赖时,如果遇到无法连接到依赖所需的服务器,需要查看所缺依赖,手动将这些依赖源码下载到$YOUR_PATH/src/对应路径下。所需依赖在Github上均有源码可以下载。

如果安装或使用dep不成功,可以跳过此步,在下一步时根据错误提示,手动安装所需依赖。

安装依赖可以使用依赖包,将依赖包的/src解压到$YOUR_PATH/gocodez目录下即可。

构建安装二进制执行码:

go clean ./...
go install ./...

安装完成后,二进制执行码放在$YOUR_PATH/gocodez/bin/中,启动时序数据库:

$YOUR_PATH/gocodez/bin/influxd

安装主从同步脚本

新建目录$YOUR_SCRIPT$YOUR_SCRIPT为自定义脚本目录:

mkdir $YOUR_SCRIPT

从Github中拉取脚本:

cd $YOUR_SCRIPT
git clone https://github.com/callELPSYCONGROO/master_slave

参考其中的README.md完成脚本配置和运行。


http://chatgpt.dhexx.cn/article/Za31LDwC.shtml

相关文章

一种破解静态链接库(.lib)的简单方法

一种破解静态链接库(.lib)的简单方法 作者:游蓝海 博客:http://blog.csdn.net/you_lan_hai 最近,在研究某代码时,遇到这样一个问题:整个解决方案中,有一个工程没有cpp源码,只有头文件跟一个静…

Linux下静态库生成和使用

一.静态库概念 1.库是预编译的目标文件(object files)的集合,它们可以被链接进程序。静态库以后缀为”.a”的特殊的存档(archive file)存储。 2.标准系统库可在目录/usr/lib与/lib中找到。比如,在类Unix系统中C语言的数序库一般…

libuvc介绍及简单使用

libuvc是一个用于USB视频设备的跨平台库,构建在libusb之上,编译libuvc时需要依赖libusb。libuvc的License为BSD,最新发布版本为0.0.6,源码地址: https://github.com/libuvc/libuvc libuvc支持在非windows系统上直接编译&#xff0…

linux下封装函数库——动态库.so和静态库.a(代码实现及链接方式)

在linux环境下的链接库分为静态链接库(.a库)和动态链接库(.so库),其作用是把C程序编译好做成一种可执行链接文件,主程序文件调用这些程序的函数接口是可以使用a库或so库,在主程序中只需要includ…

Hyperledger fabric应用的多机部署(自动化一键部署)

前面关于fabric部署的介绍都是基于单机环境下的,实际生产环境中一般会根据应用场景将节点分开部署在多台物理机上,面临的难题主要是不同主机间的节点如何通过网络进行通信。文章最后会分享一键完成多机增加组织的自动化部署脚本。 前言 这里仍然以balan…

Linux系统编程makefile制作动态库和静态库

目录 制作动态库 制作静态库 首先准备简单的add.c&#xff0c;sub.c,main.c,head.h.具体代码如下 #head.h文件 int Add(int a, int b); int Sub(int a, int b);#add.c文件 #include <stdio.h> int Add(int a, int b) {return a b; }#sub.c文件 #include <stdio.h&…

Linux动态库的下载与配置(以libevent库为例)

** Linux动态库的下载与配置 ** 本章以下载、安装、配置libevent库为例(安装libevent的前提是已经成功安装openssl库) 一、libevent的下载 https://libevent.org/ //官网下载源码包如果学习下载1.0版本为好&#xff0c;使用可以下载2.0版本 1.如果Linux已经进行桥接联网&am…

Linux下编译安装libusb动态库(.so) - libus1-0 vs libusb-0.1

最近在调试代码的过程中&#xff0c;发现libusb库中的一些方法没办法debug到&#xff0c;所以试着下载了一版源码&#xff0c;编译安装到指定的目录。这样&#xff0c;在工程的pro文件中&#xff0c;直接指定库和头文件的目录就可以引用自己编译的libusb库了。 在网上查了相关的…

linux编译生成动态库、静态库,以及使用

一、介绍 在实际开发过程中&#xff0c;当代码的文件较多&#xff0c;可以将一部分代码编译成动态库或者静态库然后再加载到程序中使用 编译过程 1、预编译 2、编译 3、汇编 4、链接 静态库和动态库的差异 1、链接静态库简单理解就是复制目标代码嵌入可执行文件中 2、动态库是…

Linux·libusb源码编译

libusb系列--Linux下libusb源码编译​​ ​ ​源码下载及解压​​ ​​下载源码​​ ​​解压下载的源码压缩包​​ ​​打开终端​​ ​​准备编译环境​​ ​​安装make dh-autoreconf​​ ​​安装 libudev-dev​​ sudo ​./autogen.sh​ ​​​​sudo ./configure --prefi…

ESP32如何用makefile直接编译生成.a静态库

目录 编译痛点前提环境编译准备makefile代码编译痛点 开发过esp系列的攻城狮们都知道,esp32的sdk包含了编译器、组件代码和例程代码,编译都是基于cmake的,都是整体一起编译,CMakeList.txt,component.mk,project.mk等等一系列和编译相关的文件,如果你想要自己编译一个自…

Linux 环境下的静态库生成与使用

目录 一&#xff0c;简介 二&#xff0c;如何生成静态链接库 1.准备测试程序 三&#xff0c;如何使用静态链接库 1.生成静态链接库 2.使用静态链接库 一&#xff0c;简介 这里我们只讲 Linux 环境下的静态库与动态库的生成与使用&#xff0c; Windows直接用VS直接就能生成…

Linux 下libusb编译与生成动态链接库

一、前言 上一篇文章提到了怎样使用Ubuntu 安装libusb&#xff0c;忘了如何将如何编译。 二、libusb使用GCC 编译 正常来讲&#xff0c;使用 gccc xxx.c -o xxx -I/usr/include -lusb-1.0 就可以了&#xff0c;如下图&#xff1a; 但是&#xff0c;当使用Ubuntu 12.04 使用…

关于libusb开源库的使用

关于libusb开源库的使用 文章目录 关于libusb开源库的使用1. 概述1.1 介绍1.2 用法 2. API接口2.1 分类2.2 初始化/反初始化2.3 获取设备2.4 打开/关闭设备2.5 根据ID打开设备2.6 描述符相关函数2.6.1 获得设备描述符2.6.2 获得/释放配置描述符 2.7 detach/attach驱动2.7.1 两种…

【Linux】 自动化编译工具make

目录 一&#xff1a;make工具 二&#xff1a;Makefile 三&#xff1a;Makefile基本规则 四&#xff1a;make是如何工作的 五&#xff1a;示例(五个阶段的Makefile) 5.1 第一阶段Makefile 5.2 第二阶段Makefile 5.3 第三阶段Makefile 5.4 第四阶段Makefile 5.5 第五阶…

【Linux操作系统】动态库,静态库的制作和使用,软链接、硬链接简介

目录 软硬链接咋创建一个软链接&#xff1f;咋创建一个软链接&#xff1f; 文件的三个时间动静态库制作静态库静态库的使用制作动态库动态库的使用 秃头侠们好呀&#xff0c;今天来说 软硬连接&#xff0c;动静态库 软硬链接 咋创建一个软链接&#xff1f; ln -s log.txt log…

【Linux】零基础学习动静态库打包

文章目录 一、软硬链接二、动静态库理解动静态库静态库的打包使用静态库打包Makefile编写动态库的打包使用动态库打包Makefile编写对于小版本的理解 总结 一、软硬链接 站在先前的讲过的文件系统的角度来看&#xff0c;下图test这个文件有自己独立的inode&#xff0c;在他的ino…

Linux | 动静态库 | 动静态链接 | makefile库打包 | 第三方库使用

文章目录 何为动静态库库文件的链接静态链接静态库打包动态链接动态库打包 第三方库的使用静态库的使用动态库的使用 在系统层面上的动态链接理解 何为动静态库 静态库(.a)&#xff1a;在程序编译链接时将静态库二进制码拷贝到程序代码中&#xff0c;程序运行时不再需要外部的静…

覆盖libc.so.6的惨痛教训

覆盖libc.so.6的惨痛教训 背景问题原因解决1、当前session未断开2、OS崩溃重启&#xff0c;所有ssh session断开 惨痛教训1、对于上产环境的内核依赖库文件不能随意覆盖、删除。2、 scp 文件覆盖问题 总结参考 背景 发生时间: 2022年11月28日08:55:20 偷了个懒&#xff0c;在安…

【Linux】自动生成makefile(ubuntu)

文章目录 前言一、Automake工具二、具体步骤1.下载Automake2.autoscan3.重命名configure.scan为configure.ac4.修改重命名后的configure.ac5.执行aclocal命令6.autoheader7.autoconf8.创建Makefile.am9.automake10.执行configure11.执行make12.执行Makefile编译完生成的可执行文…