运维知识体系

运维知识体系

运维知识体系总结,持续更新,欢迎转载。
缓存知识体系

缓存知识体系

运维知识体系之缓存,分层多级缓存体系。
DevOps学院

DevOps学院

全新体系化课程,开启运维新征程!
基础设施实践指南

基础设施实践指南

KVM、OpenStack、Docker、Kubernetes

【转载】InfluxDB 开源分布式时序、事件和指标数据库

NoSQL赵班长 发表了文章 • 0 个评论 • 2320 次浏览 • 2016-04-23 10:33 • 来自相关话题

本文转载自:https://segmentfault.com/a/1190000000444617 InfluxDB 是一个开源分布式时序、事件和指标数据库。使用 Go 语言编写,无需外部依赖。其设计目标是实现分布式和水平伸缩扩展 ...查看全部
本文转载自:https://segmentfault.com/a/1190000000444617

InfluxDB 是一个开源分布式时序、事件和指标数据库。使用 Go 语言编写,无需外部依赖。其设计目标是实现分布式和水平伸缩扩展。

特点:
  1. schemaless(无结构),可以是任意数量的列
  2. Scalable
  3. min, max, sum, count, mean, median 一系列函数,方便统计
  4. Native HTTP API, 内置http支持,使用http读写
  5. Powerful Query Language 类似sql
  6. Built-in Explorer 自带管理工具


管理界面:

1.png


API

InfluxDB 支持两种api方式
  1. HTTP API
  2. Protobuf API


Protobuf 还未开发完成, 官网文档都没有

如何使用 http api 进行操作?

比如对于foo_production这个数据库,插入一系列数据,可以发现POST 请求到 /db/foo_production/series?u=some_user&p=some_password, 数据放到body里。

数据看起来是这样的:

下面的"name": "events", 其中"events"就是一个series,类似关系型数据库的表table
[
{
"name": "events",
"columns": ["state", "email", "type"],
"points": [
["ny", "paul@influxdb.org", "follow"],
["ny", "todd@influxdb.org", "open"]
]
},
{
"name": "errors",
"columns": ["class", "file", "user", "severity"],
"points": [
["DivideByZero", "example.py", "someguy@influxdb.org", "fatal"]
]
}
]
格式是json,可以在一个POST请求发送多个 series, 每个 series 里的 points 可以是多个,但索引要和columns对应。

上面的数据里没有包含time 列,InfluxDB会自己加上,不过也可以指定time,比如:
[
{
"name": "response_times",
"columns": ["time", "value"],
"points": [
[1382819388, 234.3],
[1382819389, 120.1],
[1382819380, 340.9]
]
}
]
time 在InfluxDB里是很重要的,毕竟InfluxDB是time series database
在InfluxDB里还有个sequence_number字段是数据库维护的,类似于mysql的 主键概念

InfluxDB 增删更查都是用http api来完成,甚至支持使用正则表达式删除数据,还有计划任务。

比如:

发送POST请求到 /db/:name/scheduled_deletes, body如下,
{
"regex": "stats\..*",
"olderThan": "14d",
"runAt": 3
}
这个查询会删除大于14天的数据,并且任何以stats开头的数据,并且每天3:00 AM运行。

更加详细查看官方文档: http://influxdb.org/docs/api/http.html

查询语言

InfluxDB 提供了类似sql的查询语言

看起来是这样的:
select * from events where state == 'NY';

select * from log_lines where line =~ /error/i;

select * from events where customer_id == 23 and type == 'click';

select * from response_times where value > 500;

select * from events where email !~ /.*gmail.*/;

select * from nagios_checks where status != 0;

select * from events
where (email =~ /.*gmail.* or email =~ /.*yahoo.*/) and state == 'ny';

delete from response_times where time > now() - 1h
非常容易上手, 还支持Group By, Merging Series, Joining Series, 并内置常用统计函数,比如max, min, mean 等

文档: http://influxdb.org/docs/query_language/



常用语言的库都有,因为api简单,也很容易自己封装。

InfluxdDB作为很多监控软件的后端,这样监控数据就可以直接存储在InfluxDB
StatsD, CollectD, FluentD

还有其它的可视化工具支持InfluxDB, 这样就可以基于InfluxDB很方便的搭建监控平台

InfluxDB 数据可视化工具

InfluxDB 用于存储基于时间的数据,比如监控数据,因为InfluxDB本身提供了Http API,所以可以使用InfluxDB很方便的搭建了个监控数据存储中心。

对于InfluxDB中的数据展示,官方admin有非常简单的图表, 看起来是这样的

2.jpg


除了自己写程序展示数据还可以选择:

tasseo https://github.com/obfuscurity/tasseo/
grafana https://github.com/torkelo/grafana

tasseo

tasseo,为Graphite写的Live dashboard,现在也支持InfluxDB,tasseo 比较简单, 可以配置的选项很少。

3.png


Grafana

Grafana是一个纯粹的html/js应用,访问InfluxDB时不会有跨域访问的限制。只要配置好数据源为InfluxDB之后就可以,剩 下的工作就是配置图表。Grafana 功能非常强大。使用ElasticsSearch保存DashBoard的定义文件,也可以Export出JSON文件(Save ->Advanced->Export Schema),然后上传回它的/app/dashboards目录。

配置数据源:
datasources: {      
influx: {
default: true,
type: 'influxdb',
url: 'http://:8086/db/',
username: 'test',
password: 'test',
}
},

4.png






 

【转载】 LevelDb日知录之七如何根据Key读取记录?

NoSQL赵班长 发表了文章 • 0 个评论 • 2079 次浏览 • 2016-04-23 07:56 • 来自相关话题

郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84       LevelDb是针对大规模Key/Value数据的单机存储库,从应用的角度来看,Le ...查看全部
郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84
      LevelDb是针对大规模Key/Value数据的单机存储库,从应用的角度来看,LevelDb就是一个存储工具。而作为称职的存储工具,常见 的调用接口无非是新增KV,删除KV,读取KV,更新Key对应的Value值这么几种操作。LevelDb的接口没有直接支持更新操作的接口,如果需要 更新某个Key的Value,你可以选择直接生猛地插入新的KV,保持Key相同,这样系统内的key对应的value就会被更新;或者你可以先删除旧的 KV,之后再插入新的KV,这样比较委婉地完成KV的更新操作。     假设应用提交一个Key值,下面我们看看LevelDb是如何从存储的数据中读出其对应的Value值的。图7-1是LevelDb读取过程的整体示意图。

1.JPG


LevelDb首先会去查看内存中的Memtable,如果Memtable中包含key及其对应的value,则返回value值即可;如果在 Memtable没有读到key,则接下来到同样处于内存中的Immutable Memtable中去读取,类似地,如果读到就返回,若是没有读到,那么只能万般无奈下从磁盘中的大量SSTable文件中查找。因为SSTable数量 较多,而且分成多个Level,所以在SSTable中读数据是相当蜿蜒曲折的一段旅程。总的读取原则是这样的:首先从属于level 0的文件中查找,如果找到则返回对应的value值,如果没有找到那么到level 1中的文件中去找,如此循环往复,直到在某层SSTable文件中找到这个key对应的value为止(或者查到最高level,查找失败,说明整个系统 中不存在这个Key)。    那么为什么是从Memtable到Immutable Memtable,再从Immutable Memtable到文件,而文件中为何是从低level到高level这么一个查询路径呢?道理何在?之所以选择这么个查询路径,是因为从信息的更新时间 来说,很明显Memtable存储的是最新鲜的KV对;Immutable Memtable中存储的KV数据对的新鲜程度次之;而所有SSTable文件中的KV数据新鲜程度一定不如内存中的Memtable和 Immutable Memtable的。对于SSTable文件来说,如果同时在level L和Level L+1找到同一个key,level L的信息一定比level L+1的要新。也就是说,上面列出的查找路径就是按照数据新鲜程度排列出来的,越新鲜的越先查找。

     为啥要优先查找新鲜的数据呢?这个道理不言而喻,举个例子。比如我们先往levelDb里面插入一条数据 {key="www.samecity.com"  value="朗格科技"},过了几天,samecity网站改名为:69同城,此时我们插入数据{key="www.samecity.com"  value="69同城"},同样的key,不同的value;逻辑上理解好像levelDb中只有一个存储记录,即第二个记录,但是在levelDb中 很可能存在两条记录,即上面的两个记录都在levelDb中存储了,此时如果用户查询key="www.samecity.com",我们当然希望找到最 新的更新记录,也就是第二个记录返回,这就是为何要优先查找新鲜数据的原因。

    前文有讲:对于SSTable文件来说,如果同时在level L和Level L+1找到同一个key,level L的信息一定比level L+1的要新。这是一个结论,理论上需要一个证明过程,否则会招致如下的问题:为神马呢?从道理上讲呢,很明白:因为Level L+1的数据不是从石头缝里蹦出来的,也不是做梦梦到的,那它是从哪里来的?Level L+1的数据是从Level L 经过Compaction后得到的(如果您不知道什么是Compaction,那么........也许以后会知道的),也就是说,您看到的现在的 Level L+1层的SSTable数据是从原来的Level L中来的,现在的Level L比原来的Level L数据要新鲜,所以可证,现在的Level L比现在的Level L+1的数据要新鲜。

   证毕。

   如果您没看明白上面的证明过程,那么请记得往您的IQ卡内充值。

    SSTable文件很多,如何快速地找到key对应的value值?在LevelDb中,level 0一直都爱搞特殊化,在level 0和其它level中查找某个key的过程是不一样的。因为level 0下的不同文件可能key的范围有重叠,某个要查询的key有可能多个文件都包含,这样的话LevelDb的策略是先找出level 0中哪些文件包含这个key(manifest文件中记载了level和对应的文件及文件里key的范围信息,LevelDb在内存中保留这种映射表), 之后按照文件的新鲜程度排序,新的文件排在前面,之后依次查找,读出key对应的value。而如果是非level 0的话,因为这个level的文件之间key是不重叠的,所以只从一个文件就可以找到key对应的value。

    最后一个问题,如果给定一个要查询的key和某个key range包含这个key的SSTable文件,那么levelDb是如何进行具体查找过程的呢?levelDb一般会先在内存中的Cache中查找是否 包含这个文件的缓存记录,如果包含,则从缓存中读取;如果不包含,则打开SSTable文件,同时将这个文件的索引部分加载到内存中并放入Cache中。 这样Cache里面就有了这个SSTable的缓存项,但是只有索引部分在内存中,之后levelDb根据索引可以定位到哪个内容Block会包含这条 key,从文件中读出这个Block的内容,在根据记录一一比较,如果找到则返回结果,如果没有找到,那么说明这个level的SSTable文件并不包 含这个key,所以到下一级别的SSTable中去查找。

    从之前介绍的LevelDb的写操作和这里介绍的读操作可以看出,相对写操作,读操作处理起来要复杂很多,所以写的速度必然要远远高于读数据的速度,也就 是说,LevelDb比较适合写操作多于读操作的应用场合。而如果应用是很多读操作类型的,那么顺序读取效率会比较高,因为这样大部分内容都会在缓存中找 到,尽可能避免大量的随机读取操作。

 

【转载】 LevelDb日知录之六 写入与删除记录

NoSQL赵班长 发表了文章 • 0 个评论 • 1882 次浏览 • 2016-04-23 07:54 • 来自相关话题

郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84 在之前的五节LevelDb日知录中,朗格科技介绍了LevelDb的一些静态文件及其详 ...查看全部
郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84

在之前的五节LevelDb日知录中,朗格科技介绍了LevelDb的一些静态文件及其详细布局,从本节开始,我们看看LevelDb的一些动态操作,比如读写记录,Compaction,错误恢复等操作。       本节介绍levelDb的记录更新操作,即插入一条KV记录或者删除一条KV记录。levelDb的更新操作速度是非常快的,源于其内部机制决定了这种更新操作的简单性。

1.JPG


图6.1是levelDb如何更新KV数据的示意图,从图中可以看出,对于一个插入操作Put(Key,Value)来说,完成插入操作包含两个具 体步骤:首先是将这条KV记录以顺序写的方式追加到之前介绍过的log文件末尾,因为尽管这是一个磁盘读写操作,但是文件的顺序追加写入效率是很高的,所 以并不会导致写入速度的降低;第二个步骤是:如果写入log文件成功,那么将这条KV记录插入内存中的Memtable中,前面介绍过,Memtable 只是一层封装,其内部其实是一个Key有序的SkipList列表,插入一条新记录的过程也很简单,即先查找合适的插入位置,然后修改相应的链接指针将新 记录插入即可。完成这一步,写入记录就算完成了,所以一个插入记录操作涉及一次磁盘文件追加写和内存SkipList插入操作,这是为何levelDb写 入速度如此高效的根本原因。        从上面的介绍过程中也可以看出:log文件内是key无序的,而Memtable中是key有序的。

那么如果是删除一条KV记录呢?对于levelDb来说,并不存在立即删除的操作,而是与插入操作相同的,区别是,插入操作插入的是Key:Value 值,而删除操作插入的是“Key:删除标记”,并不真正去删除记录,而是后台Compaction的时候才去做真正的删除操作。

        levelDb的写入操作就是如此简单。真正的麻烦在后面将要介绍的读取操作中。
 

【转载】LevelDb日知录之五 MemTable

NoSQL赵班长 发表了文章 • 0 个评论 • 1883 次浏览 • 2016-04-23 07:53 • 来自相关话题

郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84  LevelDb日知录前述小节大致讲述了磁盘文件相关的重要静态结构,本小节讲述内存中的数据结构Me ...查看全部
郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84
 LevelDb日知录前述小节大致讲述了磁盘文件相关的重要静态结构,本小节讲述内存中的数据结构Memtable,Memtable在整个体系 中的重要地位也不言而喻。总体而言,所有KV数据都是存储在Memtable,Immutable Memtable和SSTable中的,Immutable Memtable从结构上讲和Memtable是完全一样的,区别仅仅在于其是只读的,不允许写入操作,而Memtable则是允许写入和读取的。当 Memtable写入的数据占用内存到达指定数量,则自动转换为Immutable Memtable,等待Dump到磁盘中,系统会自动生成新的Memtable供写操作写入新数据,理解了Memtable,那么Immutable Memtable自然不在话下。     LevelDb的MemTable提供了将KV数据写入,删除以及读取KV记录的操作接口,但是事实上Memtable并不存在真正的删除操作,删除某 个Key的Value在Memtable内是作为插入一条记录实施的,但是会打上一个Key的删除标记,真正的删除操作是Lazy的,会在以后的 Compaction过程中去掉这个KV。

     需要注意的是,LevelDb的Memtable中KV对是根据Key大小有序存储的,在系统插入新的KV时,LevelDb要把这个KV插到合适的 位置上以保持这种Key有序性。其实,LevelDb的Memtable类只是一个接口类,真正的操作是通过背后的SkipList来做的,包括插入操作 和读取操作等,所以Memtable的核心数据结构是一个SkipList。

     SkipList是由William Pugh发明。他在Communications of the ACM June 1990, 33(6) 668-676 发表了Skip lists: a probabilistic alternative to balanced trees,在该论文中详细解释了SkipList的数据结构和插入删除操作。

SkipList是平衡树的一种替代数据结构,但是和红黑树不相同的是,SkipList对于树的平衡的实现是基于一种随机化的算法的,这样也就是说SkipList的插入和删除的工作是比较简单的。

关于SkipList的详细介绍可以参考这篇文章:http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html,讲述的很清楚,LevelDb的SkipList基本上是一个具体实现,并无特殊之处。

SkipList不仅是维护有序数据的一个简单实现,而且相比较平衡树来说,在插入数据的时候可以避免频繁的树节点调整操作,所以写入效率是很高 的,LevelDb整体而言是个高写入系统,SkipList在其中应该也起到了很重要的作用。Redis为了加快插入操作,也使用了SkipList来 作为内部实现数据结构。

【转载】 LevelDb日知录之四 SSTable文件

NoSQL赵班长 发表了文章 • 0 个评论 • 2457 次浏览 • 2016-04-23 07:52 • 来自相关话题

郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84 SSTable是Bigtable中至关重要的一块,对于LevelDb来说也是如此,对LevelD ...查看全部
郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84
SSTable是Bigtable中至关重要的一块,对于LevelDb来说也是如此,对LevelDb的SSTable实现细节的了解也有助于了解Bigtable中一些实现细节。本节内容主要讲述SSTable的静态布局结构,朗格科技曾在“LevelDb日知录之二:整体架构”中说过,SSTable文件形成了不同Level的 层级结构,至于这个层级结构是如何形成的我们放在后面Compaction一节细说。本节主要介绍SSTable某个文件的物理布局和逻辑布局结构,这对 了解LevelDb的运行过程很有帮助。

LevelDb不同层级有很多SSTable文件(以后缀.sst为特征),所有.sst文件内部布局都是一样的。上节介绍Log文件是物理分块 的,SSTable也一样会将文件划分为固定大小的物理存储块,但是两者逻辑布局大不相同,根本原因是:Log文件中的记录是Key无序的,即先后记录的 key大小没有明确大小关系,而.sst文件内部则是根据记录的Key由小到大排列的,从下面介绍的SSTable布局可以体会到Key有序是为何如此设 计.sst文件结构的关键。


1.JPG


上图展示了一个.sst文件的物理划分结构,同Log文件一样,也是划分为固定大小的存储块,每个Block分为三个部分,红色部分是数据存储区,蓝色 的Type区用于标识数据存储区是否采用了数据压缩算法(Snappy压缩或者无压缩两种),CRC部分则是数据校验码,用于判别数据是否在生成和传输中 出错。    以上是.sst的物理布局,下面介绍.sst文件的逻辑布局,所谓逻辑布局,就是说尽管大家都是物理块,但是每一块存储什么内容,内部又有什么结构等。图4.2展示了.sst文件的内部逻辑解释。


2.JPG


从图4.2可以看出,从大的方面,可以将.sst文件划分为数据存储区和数据管理区,数据存储区存放实际的Key:Value数据,数据管理区则提供一些 索引指针等管理数据,目的是更快速便捷的查找相应的记录。两个区域都是在上述的分块基础上的,就是说文件的前面若干块实际存储KV数据,后面数据管理区存 储管理数据。管理数据又分为四种不同类型:紫色的Meta Block,红色的MetaBlock 索引和蓝色的数据索引块以及一个文件尾部块。

    LevelDb 1.2版对于Meta Block尚无实际使用,只是保留了一个接口,估计会在后续版本中加入内容,下面我们看看数据索引区和文件尾部Footer的内部结构。

3.JPG


图4.3是数据索引的内部结构示意图。再次强调一下,Data Block内的KV记录是按照Key由小到大排列的,数据索引区的每条记录是对某个Data Block建立的索引信息,每条索引信息包含三个内容,以图4.3所示的数据块i的索引Index i来说:红色部分的第一个字段记载大于等于数据块i中最大的Key值的那个Key,第二个字段指出数据块i在.sst文件中的起始位置,第三个字段指出 Data Block i的大小(有时候是有数据压缩的)。后面两个字段好理解,是用于定位数据块在文件中的位置的,第一个字段需要详细解释一下,在索引里保存的这个Key值未 必一定是某条记录的Key,以图4.3的例子来说,假设数据块i 的最小Key=“samecity”,最大Key=“the best”;数据块i+1的最小Key=“the fox”,最大Key=“zoo”,那么对于数据块i的索引Index i来说,其第一个字段记载大于等于数据块i的最大Key(“the best”)同时要小于数据块i+1的最小Key(“the fox”),所以例子中Index i的第一个字段是:“the c”,这个是满足要求的;而Index i+1的第一个字段则是“zoo”,即数据块i+1的最大Key。

 文件末尾Footer块的内部结构见图4.4,metaindex_handle指出了metaindex block的起始位置和大小;inex_handle指出了index Block的起始地址和大小;这两个字段可以理解为索引的索引,是为了正确读出索引值而设立的,后面跟着一个填充区和魔数。


4.JPG


上面主要介绍的是数据管理区的内部结构,下面我们看看数据区的一个Block的数据部分内部是如何布局的(图4.1中的红色部分),图4.5是其内部布局示意图。


6.JPG


从图中可以看出,其内部也分为两个部分,前面是一个个KV记录,其顺序是根据Key值由小到大排列的,在Block尾部则是一些“重启点”(Restart Point),其实是一些指针,指出Block内容中的一些记录位置。

“重启点”是干什么的呢?我们一再强调,Block内容里的KV记录是按照Key大小有序的,这样的话,相邻的两条记录很可能Key部分存在重叠,比如 key i=“the Car”,Key i+1=“the color”,那么两者存在重叠部分“the c”,为了减少Key的存储量,Key i+1可以只存储和上一条Key不同的部分“olor”,两者的共同部分从Key i中可以获得。记录的Key在Block内容部分就是这么存储的,主要目的是减少存储开销。“重启点”的意思是:在这条记录开始,不再采取只记载不同的 Key部分,而是重新记录所有的Key值,假设Key i+1是一个重启点,那么Key里面会完整存储“the color”,而不是采用简略的“olor”方式。Block尾部就是指出哪些记录是这些重启点的。


7.JPG


在Block内容区,每个KV记录的内部结构是怎样的?图4.6给出了其详细结构,每个记录包含5个字段:key共享长度,比如上面的“olor”记录, 其key和上一条记录共享的Key部分长度是“the c”的长度,即5;key非共享长度,对于“olor”来说,是4;value长度指出Key:Value中Value的长度,在后面的Value内容字 段中存储实际的Value值;而key非共享内容则实际存储“olor”这个Key字符串。

上面讲的这些就是.sst文件的全部内部奥秘。
 

【转载】LevelDb日知录之三 log文件

NoSQL赵班长 发表了文章 • 0 个评论 • 2324 次浏览 • 2016-04-23 07:46 • 来自相关话题

郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84         上节内容讲到log文件在LevelDb中的主要作用是系统故障恢复时,能够保证不会丢 ...查看全部
郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84
        上节内容讲到log文件在LevelDb中的主要作用是系统故障恢复时,能够保证不会丢失数据。因为在将记录写入内存的Memtable之前,会先 写入Log文件,这样即使系统发生故障,Memtable中的数据没有来得及Dump到磁盘的SSTable文件,LevelDB也可以根据log文件恢 复内存的Memtable数据结构内容,不会造成系统丢失数据,在这点上LevelDb和Bigtable是一致的。     下面朗格科技带大家看看log文件的具体物理和逻辑布局是怎样的,LevelDb对于一个log文件,会把它切割成以32K为单位的物理Block,每次 读取的单位以一个Block作为基本读取单位,下图展示的log文件由3个Block构成,所以从物理布局来讲,一个log文件就是由连续的32K大小 Block构成的。

3.JPG


在应用的视野里是看不到这些Block的,应用看到的是一系列的Key:Value对,在LevelDb内部,会将一个Key:Value对看做一条记录 的数据,另外在这个数据前增加一个记录头,用来记载一些管理信息,以方便内部处理,图3.2显示了一个记录在LevelDb内部是如何表示的。


4.JPG


记录头包含三个字段,ChechSum是对“类型”和“数据”字段的校验码,为了避免处理不完整或者是被破坏的数据,当 LevelDb读取记录数据时候会对数据进行校验,如果发现和存储的CheckSum相同,说明数据完整无破坏,可以继续后续流程。“记录长度”记载了数 据的大小,“数据”则是上面讲的Key:Value数值对,“类型”字段则指出了每条记录的逻辑结构和log文件物理分块结构之间的关系,具体而言,主要 有以下四种类型:FULL/FIRST/MIDDLE/LAST。        如果记录类型是FULL,代表了当前记录内容完整地存储在一个物理Block里,没有被不同的物理Block切割开;如果记录被相邻的物理Block切割开,则类型会是其他三种类型中的一种。我们以图3.1所示的例子来具体说明。

       假设目前存在三条记录,Record A,Record B和Record C,其中Record A大小为10K,Record B 大小为80K,Record C大小为12K,那么其在log文件中的逻辑布局会如图3.1所示。Record A是图中蓝色区域所示,因为大小为10K<32K,能够放在一个物理Block中,所以其类型为FULL;Record B 大小为80K,而Block 1因为放入了Record A,所以还剩下22K,不足以放下Record B,所以在Block 1的剩余部分放入Record B的开头一部分,类型标识为FIRST,代表了是一个记录的起始部分;Record B还有58K没有存储,这些只能依次放在后续的物理Block里面,因为Block 2大小只有32K,仍然放不下Record B的剩余部分,所以Block 2全部用来放Record B,且标识类型为MIDDLE,意思是这是Record B中间一段数据;Record B剩下的部分可以完全放在Block 3中,类型标识为LAST,代表了这是Record B的末尾数据;图中黄色的Record C因为大小为12K,Block 3剩下的空间足以全部放下它,所以其类型标识为FULL。

     从这个小例子可以看出逻辑记录和物理Block之间的关系,LevelDb一次物理读取为一个Block,然后根据类型情况拼接出逻辑记录,供后续流程处理。
 

【转载】LevelDb日知录之二整体架构

NoSQL赵班长 发表了文章 • 0 个评论 • 2531 次浏览 • 2016-04-23 07:43 • 来自相关话题

郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84     LevelDb本质上是一套存储系统以及在这套存储系统上提供的一些操作接口。为了便于理解整个 ...查看全部
郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84
    LevelDb本质上是一套存储系统以及在这套存储系统上提供的一些操作接口。为了便于理解整个系统及其处理流程,我们可以从两个不同的角度来看待 LevleDb:静态角度和动态角度。从静态角度,可以假想整个系统正在运行过程中(不断插入删除读取数据),此时我们给LevelDb照相,从照片可以 看到之前系统的数据在内存和磁盘中是如何分布的,处于什么状态等;从动态的角度,主要是了解系统是如何写入一条记录,读出一条记录,删除一条记录的,同时 也包括除了这些接口操作外的内部操作比如compaction,系统运行时崩溃后如何恢复系统等等方面。
      本节所讲的整体架构主要从静态角度来描述,之后接下来的几节内容会详述静态结构涉及到的文件或者内存数据结构,LevelDb日知录后半部分主要介绍动态视角下的LevelDb,就是说整个系统是怎么运转起来的。    LevelDb作为存储系统,数据记录的存储介质包括内存以及磁盘文件,如果像上面说的,当LevelDb运行了一段时间,此时我们给LevelDb进行透视拍照,那么您会看到如下一番景象:
   
1.JPG


从图中可以看出,构成LevelDb静态结构的包括六个主要部分:内存中的MemTable和Immutable MemTable以及磁盘上的几种主要文件:Current文件,Manifest文件,log文件以及SSTable文件。当然,LevelDb除了这 六个主要部分还有一些辅助的文件,但是以上六个文件和数据结构是LevelDb的主体构成元素。LevelDb的Log文件和Memtable与Bigtable论文中介绍的是一致的,当应用写入一条Key:Value记录的时候,LevelDb会 先往log文件里写入,成功后将记录插进Memtable中,这样基本就算完成了写入操作,因为一次写入操作只涉及一次磁盘顺序写和一次内存写入,所以这 是为何说LevelDb写入速度极快的主要原因。

Log文件在系统中的作用主要是用于系统崩溃恢复而不丢失数据,假如没有Log文件,因为写入的记录刚开始是保存在内存中的,此时如果系统崩溃,内存中的 数据还没有来得及Dump到磁盘,所以会丢失数据(Redis就存在这个问题)。为了避免这种情况,LevelDb在写入内存前先将操作记录到Log文件 中,然后再记入内存中,这样即使系统崩溃,也可以从Log文件中恢复内存中的Memtable,不会造成数据的丢失。

当Memtable插入的数据占用内存到了一个界限后,需要将内存的记录导出到外存文件中,LevleDb会生成新的Log文件和Memtable,原先 的Memtable就成为Immutable Memtable,顾名思义,就是说这个Memtable的内容是不可更改的,只能读不能写入或者删除。新到来的数据被记入新的Log文件和 Memtable,LevelDb后台调度会将Immutable Memtable的数据导出到磁盘,形成一个新的SSTable文件。SSTable就是由内存中的数据不断导出并进行Compaction操作后形成 的,而且SSTable的所有文件是一种层级结构,第一层为Level 0,第二层为Level 1,依次类推,层级逐渐增高,这也是为何称之为LevelDb的原因。

    SSTable中的文件是Key有序的,就是说在文件中小key记录排在大Key记录之前,各个Level的SSTable都是如此,但是这里需要 注意的一点是:Level 0的SSTable文件(后缀为.sst)和其它Level的文件相比有特殊性:这个层级内的.sst文件,两个文件可能存在key重叠,比如有两个 level 0的sst文件,文件A和文件B,文件A的key范围是:{bar, car},文件B的Key范围是{blue,samecity},那么很可能两个文件都存在key=”blood”的记录。对于其它Level的 SSTable文件来说,则不会出现同一层级内.sst文件的key重叠现象,就是说Level L中任意两个.sst文件,那么可以保证它们的key值是不会重叠的。这点需要特别注意,后面您会看到很多操作的差异都是由于这个原因造成的。    SSTable中的某个文件属于特定层级,而且其存储的记录是key有序的,那么必然有文件中的最小key和最大key,这是非常重要的信 息,LevelDb应该记下这些信息。Manifest就是干这个的,它记载了SSTable各个文件的管理信息,比如属于哪个Level,文件名称叫 啥,最小key和最大key各自是多少。下图是Manifest所存储内容的示意:

   
2.JPG


图中只显示了两个文件(manifest会记载所有SSTable文件的这些信息),即Level 0的test.sst1和test.sst2文件,同时记载了这些文件各自对应的key范围,比如test.sstt1的key范围是“an”到 “banana”,而文件test.sst2的key范围是“baby”到“samecity”,可以看出两者的key范围是有重叠的。

Current文件是干什么的呢?这个文件的内容只有一个信息,就是记载当前的manifest文件名。因为在LevleDb的运行过程中,随着 Compaction的进行,SSTable文件会发生变化,会有新的文件产生,老的文件被废弃,Manifest也会跟着反映这种变化,此时往往会新生 成Manifest文件来记载这种变化,而Current则用来指出哪个Manifest文件才是我们关心的那个Manifest文件。

【转载】LevelDb日知录之一:初识LevelDb

NoSQL赵班长 发表了文章 • 0 个评论 • 2718 次浏览 • 2016-04-23 07:32 • 来自相关话题

郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84     说起LevelDb也许您不清楚,但是如果作为IT工程师,不知道下面两位大神级 ...查看全部
郑重声明:本文转载自郎格科技系列博客,原文地址:http://www.samecity.com/blog/Article.asp?ItemID=84

    说起LevelDb也许您不清楚,但是如果作为IT工程师,不知道下面两位大神级别的工程师,那您的领导估计会Hold不住了:Jeff Dean和Sanjay Ghemawat。这两位是Google公司重量级的工程师,为数甚少的Google Fellow之二。Jeff Dean其人:

http://research.google.com/people/jeff/index.html
   Google大规模分布式平台Bigtable和MapReduce主要设计和实现者。

Sanjay Ghemawat其人:

http://research.google.com/people/sanjay/index.html

Google大规模分布式平台GFS,Bigtable和MapReduce主要设计和实现工程师。

    LevelDb就是这两位大神级别的工程师发起的开源项目,简而言之,LevelDb是能够处理十亿级别规模Key-Value型数据持久性存储的C++ 程序库。正像上面介绍的,这二位是Bigtable的设计和实现者,如果了解Bigtable的话,应该知道在这个影响深远的分布式存储系统中有两个核心 的部分:Master Server和Tablet Server。其中Master Server做一些管理数据的存储以及分布式调度工作,实际的分布式数据存储以及读写操作是由Tablet Server完成的,而LevelDb则可以理解为一个简化版的Tablet Server。

LevelDb有如下一些特点:

首先,LevelDb是一个持久化存储的KV系统,和Redis这种内存型的KV系统不同,LevelDb不会像Redis一样狂吃内存,而是将大部分数据存储到磁盘上。

其次,LevleDb在存储数据时,是根据记录的key值有序存储的,就是说相邻的key值在存储文件中是依次顺序存储的,而应用可以自定义key大小比较函数,LevleDb会按照用户定义的比较函数依序存储这些记录。

再次,像大多数KV系统一样,LevelDb的操作接口很简单,基本操作包括写记录,读记录以及删除记录。也支持针对多条操作的原子批量操作。

另外,LevelDb支持数据快照(snapshot)功能,使得读取操作不受写操作影响,可以在读操作过程中始终看到一致的数据。

除此外,LevelDb还支持数据压缩等操作,这对于减小存储空间以及增快IO效率都有直接的帮助。LevelDb性能非常突出,官方网站报道其随机写性能达到40万条记录每秒,而随机读性能达到6万条记录每秒。总体来说,LevelDb的写操作要大大快于读操作,而顺序读写操作则大大快于随机读写操作。

基于开源实现的自动化扩容-简图

SaltStack赵班长 发表了文章 • 1 个评论 • 7929 次浏览 • 2016-04-22 21:17 • 来自相关话题

好久没有写文章了,下午因为在群里有人讨论自动化扩容的话题,就顺手画了张图,直接上图。不说话。         涉及开源项目:Zabbix、Saltstack、Etcd、Haproxy、Keepalived、Mesos、Marathon ...查看全部
好久没有写文章了,下午因为在群里有人讨论自动化扩容的话题,就顺手画了张图,直接上图。不说话。

        涉及开源项目:Zabbix、Saltstack、Etcd、Haproxy、Keepalived、Mesos、Marathon、Docker、Salt-cloud、Etcd、OpenStack。注:选用etcd因为saltstack刚好有一个ectd_pillar。


auto.jpg

 

Zabbix 2.2 LTS升级到Zabbix 3.0 LTS

运维监控赵班长 发表了文章 • 1 个评论 • 8777 次浏览 • 2016-02-19 15:59 • 来自相关话题

Zabbix 3.0 LTS正式发布了,详细的功能,大家自行Google。将生产的Zabbix从2.2升级到了3.0记录一下。分为三个阶段:   升级前的准备  升级过程  升级后的检查 1.升级前准备工作: ...查看全部
Zabbix 3.0 LTS正式发布了,详细的功能,大家自行Google。将生产的Zabbix从2.2升级到了3.0记录一下。分为三个阶段:
  1.   升级前的准备
  2.   升级过程
  3.   升级后的检查


1.升级前准备工作:

1.1 Zabbix Server部署
[root@lb-node2 ~]# cd /usr/local/src
[root@lb-node2 src]# wget http://jaist.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/3.0.0/zabbix-3.0.0.tar.gz
[root@lb-node2 src]# tar zxf zabbix-3.0.0.tar.gz
[root@lb-node2 src]# cd zabbix-3.0.0
[root@lb-node2 zabbix-3.0.0]#./configure --prefix=/usr/local/zabbix-3.0.0 --enable-server \
--with-mysql --enable-ipv6 --with-net-snmp --with-libcurl --with-libxml2 \
--with-openipmi --with-ldap --enable-java
[root@lb-node2 zabbix-3.0.0]# make install

1.2 对照老版本的zabbix_server.conf进行修改,不能直接替换。
[root@lb-node2 zabbix-3.0.0]# cd /usr/local/zabbix-3.0.0
[root@lb-node2 zabbix-3.0.0]# vim etc/zabbix_server.conf

1.3 COPY相关脚本到新编译的目录下
alertscripts和externalscripts 里面的相关脚本复制到新的安装目录下。

2.Zabbix 前端部署

2.1 将新的前端PHP代码也COPY到对应的目录下。
[root@lb-node2 ~]# cp -r /usr/local/src/zabbix-3.0.0/frontends/php /usr/local/apache/htdocs/zabbix-3.0.0-frontend

2.2 修改前端PHP的配置文件
[root@lb-node2 ~]# cd /usr/local/apache/htdocs/zabbix-3.0.0-frontend/conf
[root@lb-node2 conf]# mv zabbix.conf.php.example zabbix.conf.php
[root@lb-node2 conf]# vim zabbix.conf.php


 注意:可以直接使用老的文件替换即可,内容是一样的。



2.3 把之前准备好的中文字体COPY过去。
Cp xxx.ttf  /usr/local/apache/htdocs/zabbix/fonts

3.开始升级:
     3.1 先备份

  • 1.邮件通知相干系人,将对Zabbix进行版本升级,约定升级时间。
  • 2.在约定时间到来前,对新的Zabbix Server再一次进行环境确认。
  • 3.关闭老版本的Zabbix Server,并进行代码备份(如果使用的软连接,则可以不用)
  • 4.对Zabbix数据库进行备份。(非常重要,用来升级失败的恢复!)
      3.2 创建Zabbix Server软连接到对应的位置。            你懂的,源码安装的最佳实践    3.3 启动Zabbix
  • 启动新的Zabbix服务器。(注意:日志文件,启动前把老的日志文件先重命名
  • 完全确认Zabbix数据库升级完毕后,再创建前端访问的软连接,对外提供访问。
  •  


日志:
Zabbix Server启动的时候可以关注下日志,2.x的升级会自动进行数据库的升级操作
16527:20160219:153133.851 starting automatic database upgrade



验证并邮件通知相关干系人。做事情,一定要有头有尾!