编译环境Docker化

编译代码,我喜欢操纵感强的,jenkins更适合构建,而不适合自己捣腾。
以前我们用虚拟机初始化一个环境,然后chroot,挺好,但是时常出现资源不够用的情况(很多人在一台HCI上创建虚拟机,不卡才怪),QEMU+KVM虚拟化的坏处是资源消耗太大,所以,用docker这种天生无太多牵挂的东西,性能会提高很多,而且更灵活(派生一个虚拟机和pull一个docker,感觉完全不同)。
继续阅读

MySQL galera cluster

galera cluster是一个MySQL的多主高可用方案,相对于异步复制,最大的长处是不丢数据,因为他是同步复制。

优点与缺点

优点

  1. 真正的多主模式(True Multi-master)
    意味着你可以在任意节点读写,适度的规模可以提高集群整体的性能。
    不会出现主从模式的故障转移(Master-Slave Failover)操作,也不需要VIP。
  2. 同步复制(Synchronous Replication)
    意味着没有slave lag,没有节点crash的时候出现的丢数据现象(Hot Standby)。
    并且是Multi-threaded Slave,性能也不错。
    紧耦合(Tightly Coupled)所有节点数据和状态一致。
  3. 自动节点管理(Automatic Node Provisioning)
    不需要人工去备份数据库恢复到新节点。

参考:"Benefits of Galera Cluster"
继续阅读

HA in MySQL Replication

因为aCloud原有实现就是基于半同步机制的,所以我们讲了《MySQL Semi-Synchronous Replication》,明白了半同步机制,我们再来看看目前在复制机制下的高可用实现。

为了实现HA(High Availability,高可用),引入了VIP(Virtual IP,虚拟IP)。

VIP

在master/slave的复制模型下,master对外提供写服务,slave可以不提供任何服务,只是做备份。

也有人将slave利用起来,提供读服务,就叫做读写分离,读写分离可以减轻单台服务器的压力。

不管怎么说,半同步机制是单master多slave的模式,这种模式下,只能在master上提供写服务,如果master挂了,如何保证业务连续性?

VIP原理类似DNS,在DNS中我们每次链接到一个域名,每次解析域名得到可提供服务的IP。VIP的话,我们每次在能提供服务的主机上,配置一个固有IP,如果这台主机出问题了,例如宕机了,就在其他能提供服务的节点,例如从节点配置该IP,这样用户每次链接同一个IP,也能实现高可用。 继续阅读

MySQL Semi-Synchronous Replication

半同步复制(Semi-Synchronous Replication)是相对于同步复制和异步复制而言的折中方案,当两台MySQL数据库需要同步数据,基本的复制思路如图:

master对外提供写服务,并开启binary log功能,然后slave节点启动一个IO线程来从master的binary log同步并将其写入本节点的relay log中,slave再启动一个SQL线程,从relay log中读取日志记录并插入本节点的数据库。

一切原理都是那么简单。 继续阅读

PERL单元测试简易框架

本来是写个测试脚本来测试函数是否正确,写着写着就把输出写的漂亮了些,于是将代码抽出来,做成一个公共框架。

说是框架,非常王婆卖瓜,因为就一百五十行SHELL脚本,PERL本是有单元测试的,但是我认为几行代码用那单元测试有点小题大做,最关键是,我的需求非常少,就是要跑几句代码,检测一下返回值,并且匹配一下预期数据,然后列出测试结果而已。

我之前喜欢这样简单测试PERL函数代码:

这样跑一遍,或者加-d调试一下,函数是否有问题,一下就能看出来,唯一的问题是,测试多组输入参数和输出的时候,每次都要靠双眼来对比结果是否符合预期。
继续阅读

代码上库前的自动review实现

perlcritic是一款PERL的静态代码检测工具,官网为:http://www.perlcritic.org
源码下载:https://github.com/Perl-Critic/Perl-Critic,可以参考http://search.cpan.org/dist/Perl-Critic/使用,可以使用CPAN安装:

本日志自动扫描工具建立在Critic基础上,为我们的日志检测规则写了一插件,名为RequireLogStatment,安装文件覆盖/usr/local/share/perl/5.14.2/Perl/Critic/Policy/CodeLayout/RequireLogStatment.pm 即可使用。

检测规则

针对部门使用大量PERL代码做日志规范,当前主要检查该打日志的地方未打日志的行为,该打日志的检查点为:
EXITWORD:return, exit, _exit, die

打日志的函数为:
LOGWORD:ldie lemerg lalert lcrit lerror lwarn lnotice linfo ldebug dbg1 dbg2 dbg3 dbgv

不是所有EXITWORD前都要打日志,且日志级别不一定是lerror,例如一个函数运行最后一条return语句作为合法出口不要求打日志,为了避免日志过多,建议大家按照“先处理错误,最后处理正确原则”书写代码,例如:

如果某些语句真不需要日志,可以添加annotation,规则是在语句前一条注释处加:

继续阅读

利用日志做监控

利用日志做监控,适用于不便修改源码或不便破坏现有环境时,可以通过日志内容采取不同动作,通过对日志本身的实时监控并分析,提取有效信息并采取对应行动。

应用场景可随意想象:例如,之前发现aSV的ssh密码被暴力破解,我们可以通过日志监控暴力破解行为,然后做出阻止。

这并不是一个新技术,也不困难,fail2ban http://www.fail2ban.org/ 做的挺不错,使用起来效果如图: 继续阅读

大页内存在虚拟化中的应用

原理

虚拟内存

简单说,没有虚拟内存的概念,那么COPY ON WRITE,SWAP等技术都不是必要的,但是系统的弹性和容量会大打折扣。
对比物理内存,我们可以认为虚拟内存比物理内存多许多,这个优点依赖于一个重要实现手段叫做page fault,我们将进程“分配内存”和“访问内存”概念分开,分配了内存不访问,是可以不占物理内存的(未初始化未置零等),分配了内存访问,也不一定占用更多的物理内存(COPY ON WRITE)。假设某一虚拟内存已经分配给进程A,当进程A去访问所在内存页时,可能出现:
1. 内存页已经存在于CPU Cache或物理内存,并且进程A有访问权限。这是正常情况。
2. 内存页已经存在于CPU Cache或物理内存,但是进程A还没有访问权限或者第一次访问前并没有实际载入,例如,进程A要访问libc.so的代码段,这段虚拟内存其实已经被其他进程加载到物理内存了,但是还没有赋给进程A访问权限,此时发生page fault,我们称之为minor page fault.
3. 内存页不存在于CPU Cache和物理内存。可能原因是内存已经被交换到交换分区,此时我们需要通过IO将内存页读入物理内存再给进程A访问,此过程我们称之为major page fault.

想要证明min_flt和maj_flt的发生,我们可以使用 /usr/bin/time -v CMD 来执行命令,例如,我们运行一个记事本,第一次运行的时候,会从磁盘载入共享库,所以会有Major (requiring I/O) page faults,第二次,我们先运行一个记事本程序,再使用/usr/bin/time –v运行记事本,由于使用到的共享库已经加载到内存了,我们会看到Major (requiring I/O) page faults会减少甚至为0。
继续阅读

QEMU虚拟存储的几种访问形式

存储相关命令

查看是否有FC存储:

其中ID为81:00.0 的 vendor & device ID 为 1657: 0013(上面中括号内),通过device ID,可以查找是否已经有设备驱动存在:

上面命令最后的bfa为此HBA的驱动名称,查看是否已经加载驱动:

继续阅读