InfluxDB 入门指南

本文耗时 1小时10分钟,预计阅读/实战时长 1 小时(要多练习)。

InfluxDB 用 Go 语言编写的一个开源分布式时序、事件和指标数据库,和传统是数据库相比有不少不同的地方。 类似的数据库有 Elasticsearch、Graphite 等。

一般用来储存实时数据,配合一套 UI 界面(Grafana)来展示统计信息。

安装使用

下载链接

https://portal.influxdata.com/downloads#influxdb

选择 InfluxDB (Time-Series Data Storage) V1.3.2(最新版)

根据不同的操作系统,这里提供了不同的下载安装指引。

注意:InfluxDB 的安装是需要 root 账号或者有管理员账号权限的账户。

>> 继续阅读 <<

记使用proxy_pass时遇到的一个关于路径中传参的一个有趣问题

前几天我们新开发了一个服务,需要将之前的几个接口转发到新服务的新接口上,很自然的我们只需要做一次统一转发处理接口。

我们是基于 Nginx+Lua+Openresty 构建的统一接口网关,所以处理这个问题非常简便,只需要在nginx conf中针对相应接口做一次转发即可,这里使用到 location URL 规则匹配和 proxy_pass 。

但是当我设置 location 匹配规则之后(因为有多个接口,所以匹配规则是前缀匹配),因为在转发之前,我们还有一个逻辑是处理请求的,所以调用了 lua 插件,但是就因为 lua 插件里面对于 proxy_pass 的处理,导致不能转发完整 URL 以及 URL 后面的 query 参数。

举个例子:

location /old_service/v1/old_api/ { rewrite_by_lua_file “rule.lua”; proxy_pass http://new_server/new_service/v1/module/; }

接口: /old_service/v1/old_api/get_info->/new_service/v1/module/get_info; /old_service/v1/old_api/query_info->/new_service/v1/module/query_info;

有问题的时候: new_service 接收到的接口是:/new_service/v1/module 报404-找不到相应的接口。

问题就出在:rewrite_by_lua_file “rule.lua”;

>> 继续阅读 <<

一小时入门 golang QA

本文耗时30分钟,阅读需要5分钟。

本文是《一小时入门Go语言》的答疑。希望能对一些初学者有帮助。

Q1:@ziksang go语言试用于什么方面,与node.js比价值有什么优势,有什么不如node.js? A1:Go 语言适用于所有服务器端,特别是在高并发分布式领域,他的并发特可以很容易满足你的需求

TJ 在几年前都已经转Go了。

TJ是谁? 程序员兼艺术家,Koa、Co、Express、jade、mocha、node-canvas、commander.js等知名开源项目的创建和贡献者。

对node npm社区代码贡献截止目前占到整个社区的3.04%

知乎上有这样的回答:(https://www.zhihu.com/question/24373004)

今日头条Go 语言微服务实践 http://mp.weixin.qq.com/s/CJL0Ttexvh7XT1zoNLOJrA

Q2:@Adele 哪些有名的产品或项目用了此语言? A2:Docker、TiDB、kingshard,nsq,etcd,InfluxDB,open-falcon

https://github.com/trending/go或者(掘金 Chrome 插件,关注Github上Go版块) http://awesome-go.com

Q3:@咸柠沙士 请教老师您是怎么做包依赖管理的? A3:godep,govendor,dep 目前我们团队使用govendor,基于go1.5提出来的vendor管理办法。 dep是google官方出的一个解决方案。

govendor拉github上的东西经常拉不动,有什么好的解决方法? 翻墙,或者自己clone下来到相关目录。

有人提到一些代码可以fork到coding,我的建议是直接到GitHub。

Q4:@果冻 PHP可以转型Go吗?多久或如何能精通? A4:有计算机基础一两天入门没问题,一周上手开发,精通不太好说。开发语言不一定要精通才可以养家,大家不要被精通这个字蒙蔽了双眼,要看清本质。 一个开发人员水平的高低不完全是语言本身是否精通。

Q5:@胡戎 对于依赖管理和go项目的git管理方法比如哪些文件需要放进git,clone下来后需要做什么,您能指导下吗?比如node项目clone下来直接npm install,go有gopath,管理项目应该怎么做呢?所有的的项目只要放在gopath内还是每个项目一个gopath呢?这个系统中,网关、配置中心以及请求跟踪用什么方案? A5:依赖可以放到vendor里面,也可以放在gopath下。一个项目可以一个gopath,也可以多个项目一个gopath,看你自己的实际情况和需要。

>> 继续阅读 <<

一小时入门 golang

本文耗时x分钟,阅读需要x分钟。

如何学习一门语言

学习一门新的开发语言最重要的就是做到三点:

  1. 基础知识
  2. 学习抄代码
  3. 学习写代码

服务开发语言有哪些?

  • C/C++
  • Java
  • Ruby
  • Go
  • Rust
  • PHP
  • Erlang
  • Python
  • NodeJS
  1. C/C++ 是在大学的时候学过,基本没有怎么用于实际开发,写起来很痛苦。(传统行业、腾讯系、游戏服务器等等)
  2. Java 使用过 4 年时间,主要是 J2EE 以及游戏后端服务器开发。(金融、保险等行业、阿里巴巴、京东)
  3. Ruby 使用过 1 年时间,主要是写应用的 API 接口,了解过 Ruby on Rails。(薄荷科技、其他小公司)
  4. Golang 从2015年开始使用,非常好用的一门编程语言,用起来爱不释手。(七牛,360,美图,百度,PingCAP等等)
  5. Python 一些简单的日常运维工具,或者统计分析脚本。(运维方向、机器学习/人工智能领域用的比较多)
  6. NodeJS 一般被一些前端开发工程师推崇,或者做全栈工程师推崇。
  7. Rust,Erlang 基本没怎么了解过。

C10K 和 C1000K

服务器C10K和C1000K问题

“Go not only solves C10K problem it blows it away with C1000K.”

Why Go?

Rob pike 的插图

  • 语法简单,上手快(25个关键保留字)
  • 性能高,编译快,开发效率不必Python/Ruby低
  • 部署方便,编译包小,几乎无依赖(二进制文件包可直接运行)
  • 原生支持并发(goroutine)
  • 官方统一规范(gofmt, golint…)
  • 丰富的标准库

Go 语言

Go 是 Google 开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。为了方便搜索和识别,有时会将其称为Golang。 摘自维基百科。

Go 的发展历程 enter image description here

Go 特点

  1. Go 是一种新的语言,是一种支持并发、带垃圾回收、可快速编译的静态语言。
  2. Go 为并发执行与通信提供了基本的支持,是天生的高性能服务开发语言。
  3. Go 结合了解释型语言的游刃有余,动态类型语言的开发效率,以及静态类型的安全性。
  4. Go 只需要用几秒钟的时间就可以编译一个大型的 Go 程序,部署也非常容易。
  5. Go 具有 Python/Ruby 的开发效率,同时又有 C 语言的运行性能(不过还是有一定差距的)。
  6. Go 简单(只有 25 个保留字)
  7. Go 有自己的开发规范,还提供工具支持 gofmt 格式化工具 golint 代码规范检查 go vet 可帮我们静态分析我们的源码可能存在的问题

现在也有集成度比较高的,比方说:gometalinter

>> 继续阅读 <<

给你的Github项目增加持续集成,基于travis-ci和Coveralls

本文耗时120分钟,建议实战。

简介

Travis-CI 是国外的开源持续集成构建项目,支持 Github 项目,通过 yml 配置来驱动执行相对应的持续集成脚本。对于 Github 的项目支持起来非常简单,开通 Travis 后只需要你在自己的项目根目录下增加.travis.yml就好了。

Coveralls 是一个自动化测试覆盖率的服务,它能提供代码覆盖率并且给以友好的展现。

tidb-travis-ci tidb-coveralls

如果你的项目是私有仓库的话,比方说 Gitlab,并且你的Gitlab 版本是 8.0 以上的,在Gitlab 搭建好之后就是支持 gitlab-ci 的,用法跟 Travis 类似,在项目里面根目录下增加.gitlab-ci.yml,然后你可能需要单独增加 gitlab-runner,即可进行持续集成。

更多详情,请大家看我写的另外一篇文章

持续集成Travis-ci

开通Travis

打开 travis 官网:https://travis-ci.org/

travis-ci 官网首页截屏

使用github账号授权登录。

添加项目,这里使用我的 Golang 示例项目 ratelimit。

项目选择

整个 ci 的过程有以下几步:

  1. 在 travis-ci 你的 profile 页面,勾选上你要持续集成的项目
  2. 在你的 Github 项目根目录下添加.travis.yml,Travis-CI会按照.travis.yml里的内容进行构建
  3. 提交.travis.yml到 Github,自动触发持续集成,
  4. 你可以到travis-ci-status 查看结果
>> 继续阅读 <<

Gitlab-ci 配置说明

本文耗时60分钟,建议实战。

gitlab-ci 配置说明

  1. 在项目根目录下创建一个 .gitlab-ci.yml文件,详细内容见下文源码。
  2. 修改README.md 文件,加上图标展示:(build status
  3. 提交代码,然后就可以查看到build状态了(http://xxx.gitlab.local/server/xxx/builds)

注意:经过以上3步之后,build 状态会显示[pending 状态],原因是因为还没有给他配置 Runner。

我们还要配置一下 Runner,如果没有 Runner 则可以参考这个:http://xxx.gitlab.local/server/xxx/runners 其实,Gitlab 已经有 Runner 了,可以直接用于你的项目。点击使其可用就好了。

另外:

  1. 有可能你的项目没有Pipelines,也没有Runners,所以我们需要打开 builds。(怎么打开呢?点击Edit Project,然后在Feature Visibility中找到 builds,改变权限,然后点击保存。)
  2. 这个选项是需要你上一步选择之后,才会出来:Only allow merge requests to be merged if the build succeeds。(Builds need to be configured to enable this feature.)

mr

所以,我们应该把这个选项都全部勾选上,用于要求被Merge的代码一定是通过 build 的。

>> 继续阅读 <<

gopkg.in/redis.v3 源码分析

本文耗时60分钟,阅读需要10分钟。

今天要跟大家剖析的是 redis client in golang gopkg.in/redis.v3

前文回顾

其实在此之前,我已经对这个库的源码进行过初步介绍和分析了。

Golang redis.v3源代码分析 Golang redis.v3 源代码再分析

为什么还要来分析呢?

主要是最近我们线上环境使用到redis的一个服务出现了这样的错误信息:

redis: connection pool timeout
...
redis: you open connections too fast (last error: xxx)

错误信息提示的很清楚,超时之后又是打开连接太快了。

应该不难理解,其实就是当连接池里面的连接超时不可用了之后,再重新创建,但是因为业务量对于redis连接数的诉求比较大,所以短时间内就出现了超过设定的连接池大小了,而这个错误是超过其预设连接池的2倍就会触发。

为什么是2倍呢?带着这样的问题,我就开始查看错误信息的来源[源码 gopkg.in/redis.v3/pool.go#L199]

注意我这里提供的源码项目版本是:

{
			"ImportPath": "gopkg.in/redis.v3",
			"Comment": "v3.1.4-1-g5f975ec",
			"Rev": "5f975ec92c05174cbde7254f204219ab6966c15e"
}

备注:GitHub 上已经没有3.1.4.1的分支了,那我直接给大家贴源码吧。

>> 继续阅读 <<

skiplist-跳跃链表

本文耗时60分钟,阅读需要5分钟。

今天给大家介绍一下跳跃链表。

跳跃列表由 William Pugh 发明。他在 Communications of the ACM June 1990, 33(6) 668-676 发表了Skip lists: a probabilistic alternative to balanced trees,在其中详细描述了他的工作。参见 引用并下载文档

引用发明者的话:

跳跃列表是在很多应用中有可能替代平衡树而作为实现方法的一种数据结构。跳跃列表的算法有同平衡树一样的渐进的预期时间边界,并且更简单、更快速和使用更少的空间。

在计算机科学领域,跳跃链表是一种数据结构,允许快速查询一个有序连续元素的数据链表。快速查询是通过维护一个多层次的链表,且每一层链表中的元素是前一层链表元素的子集。 

基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间)。

基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表,因此得名。所有操作都以对数随机化的时间进行。

跳跃表示例图

跳跃列表是按层建造的。底层是一个普通的有序链表。每个更高层都充当下面列表的“快速跑道”,这里在层 i 中的元素按某个固定的概率 p (通常为0.5或0.25)出现在层 i+1 中。平均起来,每个元素都在 1/(1-p) 个列表中出现,而最高层的元素(通常是在跳跃列表前端的一个特殊的头元素)在 O(log1/p n) 个列表中出现。

>> 继续阅读 <<

RocksDB介绍:一个比LevelDB更彪悍的引擎

本文耗时10分钟,阅读需要5分钟。

RocksDB介绍:一个比LevelDB更彪悍的引擎

RocksDB实际上是在LevelDB之上做的改进。本文主要侧重在架构上对RocksDB对LevelDB改进的地方做个简单介绍并添加一些个人的看法,更详细的信息读者可参考其官网:http://rocksdb.org/

RocksDB是在LevelDB原来的代码上进行改进完善的,所以在用法上与LevelDB非常的相似。从继承的角度看,Rocksdb就像是Leveldb的后辈。

RocksDB虽然在代码层面上是在LevelDB原有的代码上进行开发的,但却借鉴了Apache HBase的一些好的idea。在云计算横行的年代,开口不离Hadoop,RocksDB也开始支持HDFS,允许从HDFS读取数据。而LevelDB则是一个比较单一的存储引擎,有点我就是我,除了我依然只有我的感觉。也是因为LevelDB的单一性,在做具体的应用的时候一般需要对其作进一步扩展。

RocksDB支持一次获取多个K-V,还支持Key范围查找。LevelDB只能获取单个Key。

RocksDB除了简单的Put、Delete操作,还提供了一个Merge操作,说是为了对多个Put操作进行合并。 站在引擎实现者的角度来看,相比其带来的价值,其实现的成本要昂贵很多。

个人觉得有时过于追求完美不见得是好事,据笔者所测(包括测试自己编写的引擎),性能的瓶颈其实主要在合并上,多一次少一次Put对性能的影响并无大碍。

RocksDB提供一些方便的工具,这些工具包含解析sst文件中的K-V记录、解析MANIFEST文件的内容等。有了这些工具,就不用再像使用LevelDB那样,只能在程序中才能知道sst文件K-V的具体信息了。

RocksDB支持多线程合并,而LevelDB是单线程合并的。LSM型的数据结构,最大的性能问题就出现在其合并的时间损耗上,在多CPU的环境下,多线程合并那是LevelDB所无法比拟的。不过据其官网上的介绍,似乎多线程合并还只是针对那些与下一层没有Key重叠的文件,只是简单的rename而已,至于在真正数据上的合并方面是否也有用到多线程,就只能看代码了。

RocksDB增加了合并时过滤器,对一些不再符合条件的K-V进行丢弃,如根据K-V的有效期进行过滤。

压缩方面RocksDB可采用多种压缩算法,除了LevelDB用的snappy,还有zlib、bzip2。LevelDB里面按数据的压缩率(压缩后低于75%)判断是否对数据进行压缩存储,而RocksDB典型的做法是Level 0-2不压缩,最后一层使用zlib,而其它各层采用snappy。

在故障方面,RocksDB支持增量备份和全量备份,允许将已删除的数据备份到指定的目录,供后续恢复。

RocksDB支持在单个进程中启用多个实例,而LevelDB只允许单个实例。

RocksDB支持管道式的Memtable,也就说允许根据需要开辟多个Memtable,以解决Put与Compact速度差异的性能瓶颈问题。在LevelDB里面因为只有一个Memtable,如果Memtable满了却还来不及持久化,这个时候LevelDB将会减缓Put操作,导致整体性能下降。

看完上面这些介绍,相比LevelDB是不是觉得RocksDB彪悍的不可思议,很多该有的地方都有,该想的都想到了,简直不像在做引擎库,更像是在做产品。不过虽然RocksDB在性能上提升了不少,但在文件存储格式上跟LevelDB还是没什么变化的, 稍微有点更新的只是RocksDB对原来LevelDB中sst文件预留下来的MetaBlock进行了具体利用。

个人觉得RocksDB尚未解决的地方:

  • 依然是完全依赖于MANIFEST,一旦该文件丢失,则整个数据库基本废掉。
  • 合并上依然是整个文件载入,一些没用的Value将被多次的读入内存,如果这些Value很大的话,那没必要的内存占用将是一个可观的成本。
  • 关于这两个问题,尤其是后面那个问题,笔者已有相应的解决方案,至于结果如何只等日后实现之后再作解说了。

RocksDB介绍:一个比LevelDB更彪悍的引擎


茶歇驿站

一个让你可以在茶歇之余,停下来看一看,里面的内容或许对你有一些帮助。

这里的内容主要是团队管理,个人管理,后台技术相关,其他个人杂想。

茶歇驿站二维码

当然,你觉得对你有帮助,也可以给我打赏。 打赏

>> 继续阅读 <<

level介绍

本文耗时60分钟,阅读需要20分钟。

leveldb 介绍

LevelDB 是 Google 开源的持久化KV单机数据库,具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询较少,而写很多的场景。 LevelDB 应用了LSM (Log Structured Merge) 策略,lsm_tree 对索引变更进行延迟及批量处理,并通过一种类似于归并排序的方式高效地将更新迁移到磁盘,降低索引插入开销,关于LSM,本文在后面也会简单提及。

根据Leveldb官方网站的描述,LevelDB的特点和限制如下:

特点: 1、key和value都是任意长度的字节数组; 2、entry(即一条K-V记录)默认是按照key的字典顺序存储的,当然开发者也可以重载这个排序函数; 3、提供的基本操作接口:Put()、Delete()、Get()、Batch(); 4、支持批量操作以原子操作进行; 5、可以创建数据全景的snapshot(快照),并允许在快照中查找数据; 6、可以通过前向(或后向)迭代器遍历数据(迭代器会隐含的创建一个snapshot); 7、自动使用Snappy压缩数据; 8、可移植性;

限制: 1、非关系型数据模型(NoSQL),不支持sql语句,也不支持索引; 2、一次只允许一个进程访问一个特定的数据库; 3、没有内置的C/S架构,但开发者可以使用LevelDB库自己封装一个server;

LevelDB本身只是一个lib库,在源码目录make编译即可,然后在我们的应用程序里面可以直接include leveldb/include/db.h头文件,该头文件有几个基本的数据库操作接口。

存储流程简述

存储流程如下所示:

  • 当插入一条key-value数据时,leveldb先将数据插入到log文件(追加)中,成功后写入memtable中,既保证了高效写入,也保证了数据的稳定性
  • 当memtable插入的数据到了一个界限之后,会转为Immutable memtable, 由新的memtable支持写入操作.同时,leveldb在后台会通过调度程序将 Immutable memtable dump到磁盘上的sstable文件中。
  • sstable内部的数据是key有序的。由Immutable memtable不断dump出来的 sstable文件越来越多,会进行compact操作,形成新的level的sstable文 件。
>> 继续阅读 <<