我的CEPH分布式存储方案

1. 服务器的硬件部署

我准备了6台存储服务器用于构建Ceph分布式存储。这些服务器连接在万兆交换机上。每台存储服务器的配置如下:

(1)DELL R510服务器准系统,带2电源、2散热器、H700阵列卡带512M缓存和电池、12硬盘架。服务器内部有两个2.5寸硬盘位,外部有12个热插拔3.5寸硬盘位。
(2)使用1颗CPU,Intel XEON L5630,主频2.13GHz,睿频2.4GHz,4核心8线程,TDP 40W。由于使用了一颗低功率的CPU,能达到省电的效果。此外,管理节点使用2颗CPU。
(3)使用4根REG DDR3 PC3-10600R 4G 1333MHz三星内存条,共16G内存。此外,管理节点内存量翻倍。
(5)使用2块DELL ST9146803SS 2.5寸 10K SAS 146G硬盘组RAID1,放置于服务器内部硬盘架上,用于安装系统。
(6)使用12块DELL ST4000NM0023 3.5寸4TB SAS硬盘,放置于外部热插拔硬盘位上。拿其中11块硬盘组RAID6,其中1块硬盘做热备盘,组阵列后的有效容量为36TB。
(7)将1块容量1TB、m.2接口、PCIE协议的nvme固态硬盘插入转接卡中后,插入到服务器的PCI-E 2.0接口上,用于机械硬盘的缓存,增加分布式存储的吞吐量(IOPS)。
(8)使用一张DELL万兆光纤网卡通过DELL单模光模块和单模光纤跳线连接到DELL万兆路由器上。

在Ceph说明文档中,一般推荐在管理节点硬件上使用更好的CPU和更大的内存量,推荐至少4核心CPU、8GB内存。而存储节点仅仅使用CRUSH算法计算数据的存放,消耗CPU和内存较少,推荐至少2核心CPU、2GB内存。当然,内存越大越好,特别是最新版本的Ceph使用Bluestore数据存储方法,它利用到内存来缓存数据。设置参数osd_memory_target值为4GB能保证OSD(Object Storage Device)的性能,设置该参数更大的值能对性能提升有帮助,适合于小文件存储和OSD容量较大(>=256GB)的情况。

在我的Ceph集群中,每台存储服务器使用阵列卡将12块硬盘做成一个RAID磁盘,将该RAID磁盘和nvme固态硬盘合并做一个大容量的OSD,设置osd_memory_target值为为12GB。这样能消耗较小的计算量和内存,因此选用的CPU偏向节能,内存也较少,更加经济。而常规的Ceph集群一般不使用RAID卡做磁盘阵列,让磁盘直接连接到服务器主板,并让每块物理机械硬盘单独做一个OSD,每个OSD都消耗内存和CPU资源,其物理磁盘数量越多,消耗的CPU资源和内存也越大,但是性能更好。因为组RAID阵列后的总体性能一般小于所有物理磁盘性能之和,特别是磁盘数量越多的时候,RAID卡成了磁盘性能的瓶颈。

2. Ceph集群中服务器的系统安装和基础配置

2.1 安装CentOS8系统

我在每台服务器上安装CentOS-8.1.1911-x86_64系统,并使用最大化安装方法:在Software Selection项目中左边栏每点击一项,右边栏都勾上所有软件,最后左边栏勾选Server with GUI,右边栏不要勾选.NET Core Development。安装完毕系统后,全程使用root用户进行后续的操作。

2.2 主机名设置

分别对每台节点设置主机名。例如,对第一台节点(管理节点)设置主机名,使用root用户执行:

cat << EOF > /etc/hostname
ceph1
EOF

cat << EOF > /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=ceph1
EOF

cat << EOF > /proc/sys/kernel/hostname
ceph1
EOF

每台节点设置不一样的主机名,编号为ceph1、ceph2、ceph3 …

2.3 网卡IP设置

推荐在CentOS8系统图形化桌面界面中,左键单击击屏幕右上角位置,打开控制面板界面,点击网络设置选项卡,然后对目标网卡进行固定IP设置,并允许开机启动。设置完毕以后,则可以获得内网固定IP。若需要修改其IP信息,可以使用如下命令行进行修改。例如,对第一台节点设置其IP信息,使用root用户执行:

perl -p -i -e 's/IPADDR=.*/IPADDR=192.168.160.151/' /etc/sysconfig/network-scripts/ifcfg-ens33
perl -p -i -e 's/ONBOOT=.*/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-ens33
perl -p -i -e 's/PREFIX=.*/PREFIX=24/' /etc/sysconfig/network-scripts/ifcfg-ens33
perl -p -i -e 's/GATEWAY=.*/GATEWAY=192.168.160.2/' /etc/sysconfig/network-scripts/ifcfg-ens33
perl -p -i -e 's/DNS1=.*/DNS1=192.168.160.2/' /etc/sysconfig/network-scripts/ifcfg-ens33

systemctl restart network.service

2.4 将主机名和IP对应

在每台节点上生成生成/etc/hosts文件,囊括所有主机IP信息,在每台节点上使用root用户执行:

cat << EOF >> /etc/hosts
192.168.160.151 ceph1
192.168.160.152 ceph2
192.168.160.153 ceph3
192.168.160.154 ceph4
192.168.160.155 ceph5
192.168.160.156 ceph6
EOF

2.5 设置root用户无密码SSH登录各节点

将root用户设置成无密码ssh登录,保证在任何节点上都可以无密码直接登录其它任意节点。使用root用户在ceph1节点上进行操作:

# 生成rsa密钥对
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

# 将公钥上传给ceph2节点
ssh-copy-id ceph2

# 将授权文件copy到ceph1
scp ceph2:~/.ssh/authorized_keys ~/.ssh/

# 将包含密钥对,授权文件的~/.ssh文件夹拷贝给所有节点,包括ceph1自己
scp -r ~/.ssh ceph1:~/
scp -r ~/.ssh ceph2:~/
scp -r ~/.ssh ceph3:~/
scp -r ~/.ssh ceph4:~/
scp -r ~/.ssh ceph5:~/
scp -r ~/.ssh ceph6:~/
scp -r ~/.ssh ceph7:~/
# 每copy一次的时候,都要识别主机,输入yes和密码。拷贝成功后,则可以无密码SSH登录了。
# 以上scp命令运行成功后,则ceph1中的~/.ssh/known_hosts记录了所有的主机信息。而其它节点的该文件依然只记录了一部分主机信息。将以上命令一次性再全部运行一遍,则保证所有节点中的~/.ssh文件夹内容一致了,完全实现普通用户在各节点间无密码SSH登录。

2.6 启用Aliyun、EPEL和Ceph的YUM源

启用Aliyun源能让国内的软件下载速度更快,启用Extra Packages for Enterprise Linux (EPEL) 源能安装更多第三方软件,启用Ceph源有利于部署Ceph软件。使用root用户在每台节点上进行操作:

# 若已经安装EPEL和Ceph源,可以先删除软件和其配置文件
yum erase -y ceph-release epel-release 
/bin/rm -rf /etc/yum.repos.d/ceph.repo* /etc/yum.repos.d/epel.repo*

# 启用Aliyun镜像源:
/bin/mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
wget http://mirrors.aliyun.com/repo/Centos-8.repo -O /etc/yum.repos.d/CentOS-Base.repo

# 启用EPEL源:
yum install -y epel-release

# 启用Ceph源(对于CentOS8,推荐使用最新octopus版本或luminous版本):
rpm -Uvh https://download.ceph.com/rpm-octopus/el7/noarch/ceph-release-1-1.el7.noarch.rpm
# 以上命令生成/etc/yum.repos.d/ceph.repo文件,推荐对该文件内容进行修改,换成Aliyun镜像,速度更快
perl -p -i -e 's/download.ceph.com/mirrors.aliyun.com\/ceph/' /etc/yum.repos.d/ceph.repo

2.7 开启时间同步服务

在所有 Ceph 节点上安装并运行chrony服务,特别是监控节点,以免因时钟漂移导致故障。在每个节点上使用root用户进行操作:

# CentOS8系统使用chrony进行时间同步服务
systemctl restart chronyd.service
systemctl enable chronyd.service

# 若是CentOS7系统,则使用ntp服务
yum install -y ntp ntpdate ntp-doc
systemctl restart ntpd.service
systemctl enable ntpd.service

2.8 开放防火墙端口

Ceph的监控节点之间默认使用3300 / 6789端口通信, 存储节点之间默认用6800:7300这个范围内的端口通信,管理节点需要使用8843 / 9283端口。虽然Ceph软件部署时会自当开放其中一些端口,但推荐在各节点上先手动开放这些端口更好,有些端口软件部署时没有自动开放。使用root用户操作:

firewall-cmd --zone=public --add-port=3000/tcp --permanent
# 端口3000用于在网页管理界面展示性能统计信息(CPU内存网络消耗等)。
firewall-cmd --zone=public --add-port=3300/tcp --permanent
firewall-cmd --zone=public --add-port=6789/tcp --permanent
firewall-cmd --zone=public --add-port=8443/tcp --permanent
firewall-cmd --zone=public --add-port=9283/tcp --permanent
firewall-cmd --zone=public --add-port=6800-7300/tcp --permanent
systemctl restart firewalld.service
systemctl enable firewalld.service
firewall-cmd --list-ports

3. 部署Ceph存储集群系统

3.1 Ceph软件简介

从我的角度看,Ceph软件用于搭建分布式存储集群,将多台存储服务器上磁盘分区整合成一个容量更大、性能更强、价格更便宜、数据可靠性较高的文件系统。

在存储集群中,存在如下几种服务器:(1)监控节点,用于监控管理节点、OSD、元数据服务器和CRUSH等运行的状态,这对集群的稳定运行是必不可少的,有利于集群中各节点的相互交流。因此,一般最少有3各监控节点来保证高可用性。(2)管理节点,用于收集和统计运行数据,对性能和负载进行分析,并提供WEB控制界面和REST API。正常情况下需要至少2个管理节点来保证高可用性。(3)OSD(Object Storage Daemon)节点,用来存储数据,并将相关信息提供给监控节点和管理节点。一般需要最少3个OSDs来做保证数据冗余和高可用性。(4)元数据服务器(Metadata Server / MDS),用来存储元数据, 有利于提供文件系统服务,然后就可以将分布式存储的文件系统挂载到多台客服机上。正常情况下需要至少2个Meta节点来保证高可用性。

3.2 Ceph集群进行数据存储的简单原理

CEPH能将多台存储服务器的存储空间合并为一个整体,得到一个容量超级大的虚拟磁盘设备,或者说一个容量超级大的分区(文件系统)。当我们将一个文件写入该分区中时,Ceph将该文件分割成很多大小为4MB的objects(小文件碎片),每个object随机均匀地保存到ceph集群中各节点的各物理磁盘上。若写入或读取的文件很大,则得到很多个objects,这些objects可以随机均匀地存储到集群中各存储设备(OSD / object storage device)上,那么其读写速度则非常非常快。这就是Ceph分布式存储的最大优点,即吞吐量非常大。此外,Ceph整合许多台存储服务器,则其容量也可以非常非常大。

为了让Ceph得到较好的存储可靠性,则其关键的是如何将object存储到各节点中的OSDs上。服务器节点多,每个节点下可能会有多个OSDs,它们都可能会出现无法访问的情况,因此ceph可以使用多副本和纠删码两种备份机制中的一种。(1)多副本方法,让每个object保存到多个不同节点的OSDs中。ceph默认使用了3副本方法,则表示object保存到了3个不同的OSDs,从而实现数据安全,但是这样会让有效的存储空间降到三分之一。即使使用2副本的方法,也只有50%的空间利用率。但是Ceph的多副本的方法能获得最好的性能。(2)纠删码方法,则是将数据分割成k份,再根据这k份数据计算出m份同样大小的纠删码数据,将数据保存到k+m个不同的OSDs上。若某一份数据丢失,则可以根据仍然存在的>=k份数据计算出丢失的数据,从而获得完整的数据。只要不超过m份数据丢失,则数据依然可以根据通过解码方法计算出完整的数据。对于纠删码的简单理解:1+2+3+4=10,根据前面4份数据,算出了第5份数据的值;当某一份数据丢失时,1+x+3+4=10,则可以根据纠删码的数据算出丢失的数据x=2,从而获得完整的数据。纠删码方式存储数据的好处是能获得更高的空间利用率。例如,k=4,m=1的空间利用率为80%,k=8,m=2的空间利用率也为80%。但是前者是解一元方程,后者是解二元方程,其计算量更大,但是允许故障的OSDs更多。因此,纠删码方法存储数据会消耗较大的计算量,建议给服务器配置更多的CPU线程。特别是当某个OSDs出故障情况下,对整个OSD的数据重建会消耗极大的计算资源和网络负荷。因为该OSD中数据可能和其他所有的OSDs都有联系,对该OSD数据进行重建,需要读取其他OSDs的数据并进行计算恢复。而多副本的方法,则只需要复制相应的数据即可。此外,将一个object存储到多个OSDs,描述其存放位置的术语为放置组(PG / Placement Group),即一个object数据是保存到一个PG中的。而PG如何映射到不同节点上的多个OSDs中,保证数据可靠性,则是 使用CRUSH算法进行

3.3 部署Ceph软件到管理节点

目前(2020.06.10),最新版本的Ceph为V15.2.3,其版本名称为octopus。值得注意的是,每个大版本的Ceph都赋予了一个专门的名称。我个人强烈推荐使用最新版本的Ceph,因为每次更新都有很多更先进的设置,能获得更好的性能。当前octopus版本和以前的版本相比,改变巨大,其安装方法和使用方法有了很大的改变。目前虽然有4种方法用于部署Ceph软件,但官方推荐使用cephadm安装octopus版本的Ceph。它最为简单快捷,容易成功。

首先,安装cephadm软件。它是Ceph的管理软件,可以用于ceph的部署和卸载。推荐在集群所有节点中都安装cephadm、ceph-common和ceph-osd这3个软件。ceph-common能生成命令ceph,用于查看集群状态,管理集群配置。ceph-osd能对集群的OSD进行操作。

for i in `perl -ne 'print "$1\n" if m/(ceph\d+)/' /etc/hosts`
do
    scp /etc/yum.repos.d/*.repo $i:/etc/yum.repos.d/
    ssh $i "yum install -y epel-release cephadm ceph-common ceph-osd"
done
# 需要先安装ceph和epel的yum源(见2.6步骤),才能安装cephadm、ceph-common和ceph-osd这些和ceph相关的软件。

然后,在管理节点上,部署Ceph管理服务、监控服务:

# 使用cepham命令在第一台管理节点ceph1上安装Ceph软件。
mkdir -p /etc/ceph
cephadm bootstrap --mon-ip 192.168.160.151 &> cephadm.log

以上操作在目标节点上部署了Ceph的管理和监控服务,并生成了如下重要文件:

/root/.ssh/authorized_keys
    SSH的授权登录文件,有利于SSH的无密码登录。
/etc/ceph/ceph.conf
    Ceph的配置文件。该配置文件包含最简单的配置信息:使用fsid标识了该存储集群的文件系统id。此外,根据命令中给定的主机名,在ceph.conf配置文件中也设置了对应的监控节点主机名和IP信息。推荐需要额外增加一些必须的参数,来保证Ceph的稳健运行。
/etc/ceph/ceph.client.admin.keyring
    记录Ceph客户端使用的用户和密码。若在客户端上挂在Ceph文件系统,则需要使用该文件中记录的明文用户名和密码。
/etc/ceph/ceph.pub
    SSH的公钥文件。需要将该文件信息追加到集群中每台服务器的/root/.ssh/authorized_keys文件尾部,以利于各集群服务器之间的SSH访问。因此安装完毕Ceph软件后,要将本教程中2.5部分的scp命令重新执行一遍,保证所有节点中的/root/.ssh/authorized_keys文件内容是一致的,有利于各节点之间的无密码SSH登录。

Ceph的配置文件一般需要修改:

cat << EOF >> /etc/ceph/ceph.conf
osd_pool_default_size = 3
osd_pool_default_min_size = 2
osd_pool_default_pg_num = 512
osd_pool_default_pgp_num = 512
mon_allow_pool_delete = true
EOF
perl -p -i -e 's/^\s*//' /etc/ceph/ceph.conf

systemctl restart ceph.target

在ceph1节点上安装Ceph软件完毕后,软件在屏幕上输出了一些网页使用的提示信息。则可以打开该节点上的firefox软件,打开其中的网址,输入用户名和密码进入Ceph的网页管理界面。

INFO:cephadm:Ceph Dashboard is now available at:
URL: https://ceph1:8443/ User: admin Password: p67wjmjana
INFO:cephadm:You can access the Ceph CLI with:
sudo /usr/sbin/cephadm shell --fsid 35b1d70e-a68c-11ea-9e33-000c29de8f44 -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring
INFO:cephadm:Please consider enabling telemetry to help improve Ceph:
ceph telemetry on
For more information see:
https://docs.ceph.com/docs/master/mgr/telemetry/
INFO:cephadm:Bootstrap complete.

3.4 添加其他主机并部署多个主机的监控服务和元数据服务

添加其他多个主机作为存储集群的节点:

# 查看当前的主机
ceph orch host ls

# 添加主机前先在每个节点ssh授权文件中添加授权信息
cat /etc/ceph/ceph.pub >> ~/.ssh/authorized_keys
for i in `perl -ne 'print "$1\n" if m/(ceph\d+)/' /etc/hosts`
do
    scp -r ~/.ssh $i:~/
done

# 再添加主机
ceph orch host add ceph2
ceph orch host add ceph3
ceph orch host add ceph4
ceph orch host add ceph5
ceph orch host add ceph6

当添加其他主机后,Ceph会自动在其它一台主机上部署管理服务,在其它两台主机上部署监控服务。一般推荐最少3台监控主机,2台管理主机。若需要在更多主机上部署监控服务:

ceph orch apply mon ceph1,ceph2,ceph3,ceph4
# 注意一定要包含至少一台当前部署了监控服务的主机,例如ceph1,否则程序会先删除在该列表中不存在的主机的监控服务,导致没有监控服务存在了,从而ceph无法运行,无法再重新部署新的监控主机。
# 部署监控主机可能需要等待较长时间。

在指定的主机上部署元数据服务(推荐在Ceph文件系统做好以后再执行,因为输入信息中包含对应文件系统的名称):

ceph orch apply mds cephfs ceph5,ceph6

操作完毕后,查看集群运行状态:

ceph -s
ceph orch ls

3.5 在各存储节点上部署OSD

Ceph软件的octopus版本推荐使用性能更好的BlueStore来进行OSD部署,一开始就接管没有任何分区信息的裸磁盘,能获得更好的性能。此外,还支持使用高速固态硬盘的裸磁盘或GTP分区进行辅助,增加OSD速度。若一个高速固态硬盘给一个机械硬盘OSD加速,则不用对固态硬盘进行分区;若一个高速固态硬盘给多个机械硬盘OSD进行加速,则使用parted命令对高速固态硬盘进行GPT分区。前者推荐使用网页管理界面进行OSD部署,和网页管理方式更兼容;后者推荐用命令行进行操作,网页官界面貌似不能将裸机械磁盘和固态硬盘的GPT分区合并做OSD,但可能和网页管理方式不兼容,导致网页管理中心跳会变黄色warning状态,提示管理不了OSDs。

推荐在网页中打开ceph的管理界面,依次点击Cluster——OSDs——Create,操作OSDs的添加,这样更加方便快捷。注意每添加一个OSD,等一会儿,待该OSD添加到集群中了,再添加下一个OSD。OSDs的设备包含3种

Primary devices (block):一般是各存储节点上的各存储设备,一块块的物理磁盘或阵列卡合并出的虚拟磁盘。

DB device (block.db):可选的设备,用于存放OSD的中间元数据(可以理解为ceph分布式存储集群运行过程中的各种状态信息,这些数据的信息量很大且非常碎片化,以数据库的方式存储)。一般推荐使用SSD固态硬盘存储这些信息,这样才能保证Ceph软件能快速读写元数据,维持软件的高效运行。Ceph会将要存储的元数据会尽可能存储到该设备上,只有当该设备写满后,才会将溢出的数据写入到Primary device。因此,该设备的性能要超过Primary device的性能才有意义。该设备的容量越大越好,一般推荐其容量为Primary device的1%到4%。特别是当ceph集群用于对象存储RGW时,其需要存储的元数据更大,该比例需要超过4%。而ceph集群用作块存储时,则通常1%到2%则足够。

WAL device (block.wal):可选的设备,用于存放journal或者write-ahead数据,一般使用速度更快的nvme固态硬盘会更加有意义。可以理解这个设备就等同于阵列卡的缓存,所有需要读写的文件数据都会先经过该设备,再写入分区中。

不推荐使用价格便宜的SSD硬盘用作DB/WAL设备。例如,有些价格便宜且容量较低的SSD固态硬盘连续写入速度可能只有200M/s,才和普通SAS机械硬盘的速度相当,则不能提高OSD的连续写入速度。也不推荐单块SSD硬盘同时和过多的Primary devices对应。例如,2块900G的SAS SSD硬盘配36块10TB SAS硬盘,则每块SSD对应18块SAS机械硬盘,单块SAS SSD的连续读写极限速度才550M/s,而18块SAS的连续读写速度之和约3.6G/s,这样使用SSD后虽然对IOPS性能有增加,但极大降低了Ceph集群的连续读写速度。

当快速存储设备容量较小(<1G)的时候,则推荐仅用来做WAL device;若容量较大,则推荐做DB device,此时若不做WAL,则缓存(journal)数据会自动存放到最快的设备上。

因此,推荐的方案是:当同时有SSD和nvme时,使用SSD作DB设备,使用nvme作WAL设备;当仅有SSD或nvme其中一种时,使其作DB设备即可。 

也可以使用命令行进行OSDs部署。相比于网页管理界面,命令行能批量化进行操作,适用于服务器中机械硬盘数量较多,创建的OSDs数量较多情况下的批量化处理。此外,命令行能较好支持一个高速硬盘的GPT分区运用到多个OSDs中。而网页管理界面中貌似不能支持,仅支持整个高速固态硬盘支持一个OSD。

# 查看集群中各节点可以进行OSD部署的设备详情
ceph orch device ls

# 使用ceph-volume(需要安装ceph-osd)准备OSD
# 仅仅使用机械硬盘做OSD,要求磁盘不能有分区信息
# ceph-volume lvm prepare --bluestore --data <device>
# 指定WAL / DB设备做OSD时,要求这两种设备是逻辑卷或GTP分区
# ceph-volume lvm prepare --bluestore --data <device> --block.wal <wal-device> --block.db <db-device>
# 在我的Ceph方案中,一个存储节点,只有一个RAID磁盘作block,一个固态硬盘作block.db
ceph-volume lvm prepare --bluestore --data /dev/sdb --block.db /dev/nvme0n1
# 可能会提示错误:[errno 13] RADOS permission denied (error connecting to the cluster)
# 则需要相应的密钥,采用如下命令生成密钥后再进行OSD准备
ceph auth get client.bootstrap-osd > /var/lib/ceph/bootstrap-osd/ceph.keyring

# 激活OSD,将该OSD增加到Ceph集群中,需要输入osd编号和osd的fsid
ceph-volume lvm activate --bluestore 1 0928d5cb-29ed-48c0-bf4a-195d12e973be
# 或者使用--all直接激活所有的OSDs。一般推荐将所有OSD准备好后,一次性让所有OSD激活,这样有利于数据的均衡。
ceph-volume lvm activate --bluestore --all
# 未激活的OSD在网页管理界面中属于down的状态,激活的OSD属于up状态。

# 若之前已经做过OSD的,使用如下命令删除其OSD,有利于重新部署OSD。
# 检测当前可用于做OSD的设备
ceph-volume inventory
# 列出当前的osd设备信息
ceph-volume lvm list
# 毁掉当前的osd设备,让磁盘成为裸盘
ceph-volume lvm zap --osd-id 7
ceph-volume lvm zap /dev/sdb --destroy
ceph-volume lvm zap /dev/nvme0n1 --destroy
# 进行以上删除操作前后,推荐重启服务器,否则可能不能刷新,导致不饿能重新部署OSD

3.6 部署Ceph的逻辑分区POOL

Ceph通过存储池(pool)来存储数据,相当于Ceph集群系统整合多台服务器得到大磁盘的逻辑分区。不同的pool分区有不同的数据存放规则,它管理着PG、CRUSH规则和数据备份机制,即object在PG中如何使用CRUSH规则,依照何种备份方法存放到OSDs中,从而让数据存储到Ceph集群上。注意的是,默认设置下逻辑分区pool是动态的,没有固定容量大小,能一直使用,直到达到最大容量。这和动态磁盘是一样的,好处是可以随时扩容。

创建pool,首先需要设置该pool的PG数量。一般来说,单个OSD的PG数量设置到100左右,能在较好的性能和较低的计算量之间取得平衡。当选择多副本备份机制时,pool的PG数量为:100 * OSD数量 / 副本数;当选择纠删码备份机制时,pool的PG数量为:100 * OSD数量 * k / (k+m)。最后pool的PG数量设置为2的n次方的一个值,该值最接近按以上方法算出来的PG数。例如,我的Ceph方案中,使用纠删码k=5 / m=1,PG数量应该要接近 100 * 6 * 5 / 6 = 500,故选择pg值为512。推荐在/etc/ceph/ceph.conf 配置文件中设置pg值,若不设置的话,其默认pg和pgp值都是32。

使用多副本的方法创建一个存放元数据的pool:

ceph osd pool create cephfs_metadata 128 128 replicated

使用纠删码方法创建一个存放文件数据的pool,需要先设置其备份机制参数

# 创建一个名为myprofile的参数配置
ceph osd erasure-code-profile set myprofile k=4 m=1 crush-failure-domain=host
# 以上设置k=4/m=1,则空间利用率为很高,为80%。

# 删除纠删码配置信息
ceph osd erasure-code-profile rm myprofile
# 查看纠删码参数信息
ceph osd erasure-code-profile get default
ceph osd erasure-code-profile get myprofile
# 查看纠删码参数信息名称
ceph osd erasure-code-profile ls

# 使用纠删码方法创建pool
ceph osd pool create cephfs_data 128 128 erasure myprofile

# 查看pools信息
ceph osd lspools

3.7 部署Ceph文件系统RADOS

Ceph的文件系统可以用于其他服务器的挂载和使用,称为RADOS(Reliable, Autonomic Distributed Object Store)。该文件系统需要两个pools:一个pool用于存放元数据,必须要使用多副本备份机制,因为元数据丢失会导致存储集群系统无法访问;另一个pool用于存放文件数据,可以使用纠删码备份机制,这时必须要求OSDs使用BlueStore数据存储方式。

# 使用EC pool需要设置该pool的allow_ec_overwrites参数值为true
ceph osd pool set cephfs_data allow_ec_overwrites true

# 利用两个pools创建名为cephfs的文件系统
ceph fs new cephfs cephfs_metadata cephfs_data --force

# 查看文件系统名称或其详情
ceph fs ls
ceph fs dump

# (可选)默认ceph文件系统运行最大存放单个文件大小1TB,增大10倍阈值
fs set cephfs max_file_size 10995116277760

# 文件系统创建好后,查看元数据服务处于激活的状态
ceph mds stat

4. Ceph集群系统的使用

4.1 挂载Ceph文件系统

在局域网内任意机器上使用mount命令挂载Ceph文件系统:

# 必须使用管理节点的IP来挂载。
mount -t ceph 192.168.160.151:/ /mnt/ -o name=admin,secret=AQCB+d9e33rCMxAA+O3Cpk3p1yEWkL4hJnQ+EA==

# 其中的用户名和密码查询/etc/ceph/ceph.client.admin.keyring文件。或使用如下命令获取
ceph auth get client.admin
ceph auth ls

我使用虚拟机做测试,每个虚拟机用15G的虚拟磁盘安装系统,用20G的虚拟SATA磁盘作OSD的block,用8GB的虚拟磁盘作OSD的block.db。使用纠删码(k=4/m=1)方式做data pool,使用3副本方式做metadata pool。挂载ceph文件系统的容量为85GB,即空间有效率为85/120=70.8%。

4.2 管理和使用Ceph集群系统的常用ceph命令

查看ceph集群状态:

ceph -s
# -s | --status参数能打印出当前集群状态。
ceph -w
# -w | --watch参数和-s参数一样,但是能实时动态显示集群状态。

集群管理orchestrator模块用于对主机和磁盘设备进行管理:

# 查看集群中各组分的状态
ceph orch ls

# 查看集群中的主机名称
ceph orch host ls
# 添加主机
ceph orch host add <hostname>
# 删除主机
ceph orch host rm <hostname>

# 查看集群中各主机下的磁盘信息
ceph orch device ls [hostname]
# 对集群中某个主机的磁盘进行zap,即删除磁盘分区信息,还原成裸磁盘状态,有利于OSD的创建。
ceph orch device zap <hostname> <path> --force

对集群中的OSDs进行操作:

# 对OSDs的名称、结构、状态和使用率进行查询
ceph osd ls
ceph osd tree
ceph osd status
ceph osd df          # df即disk 

# 对pool的名称和状态进行查看
ceph osd lspools
ceph osd pool ls
ceph osd pool stats [pool_name]

# 查看pool的副本数、纠删码的k/m值和pg[p]数
ceph osd pool get <pool_name> size
ceph osd pool get <pool_name> min_size
ceph osd pool get <pool_name> pg_num
ceph osd pool get <pool_name> pgp_num
ceph osd dump    # 导出pool的详细信息

4.3 Ceph分布式存储集群的全体关机和开机

由于Ceph集群的备份机制,若直接关闭某个主机,系统认为相应的OSDs挂掉,导致数据平衡操作发生,对数据的安全有一定影响。因此,关机需要对数据进行停止读写,并关闭备份机制,然后依次关闭纯OSD主机、元数据主机、监控主机、备用管理主机,最后关闭管理主机。开机的时候依次开启纯OSD主机、元数据主机、监控主机、管理主机和备用管理主机。

# 关闭数据读写和备份机制
ceph osd set noout
ceph osd set norecover
ceph osd set norebalance
ceph osd set nobackfill
ceph osd set nodown
ceph osd set pause

# 依次关闭纯OSD主机、元数据主机、监控主机、备用管理主机和管理主机
# 依次开启纯OSD主机、元数据主机、监控主机、管理主机和备用管理主机

# 开启数据读写和备份机制
ceph osd unset noout
ceph osd unset norecover
ceph osd unset norebalance
ceph osd unset nobackfill
ceph osd unset nodown
ceph osd unset pause

5. 卸载Ceph集群系统

卸载之前,先使用umount在相关节点中卸载ceph文件系统。若操作不成功,添加 -l 参数强行卸载,然后开始Ceph卸载。

首先,在管理节点上操作,删除所有demons:

cephadm rm-cluster --force --fsid `perl -ne 'print $1 if m/fsid = (\S+)/' /etc/ceph/ceph.conf`

再分别在各个节点上操作,以root权限进行操作:关闭ceph相关进程,删除OSDs,卸载ceph相关软件,删除ceph残留文件。

# 关闭名称中含有ceph关键词的所有进程
kill -s 9 `ps -aux | grep ceph | perl -ne 'print "$1 " if m/\s+(\d+)/'`

# 批量删除OSDs,将所有参与OSDs的磁盘恢复成裸磁盘
ceph-volume lvm list | perl -ne 'print "ceph-volume lvm zap --osd-id $1\n" if m/=+\s+osd\.(\d+)\s+=+/; print "ceph-volume lvm zap $1 --destroy\n" if m/\s*devices\s*(\S+)/' | sh
# 检测OSD是否存在
ceph-volume lvm list

# 卸载以ceph字符开头的系统软件
yum remove -y `rpm -qa | grep -P "^ceph" | perl -pe 's/\n/ /'`

# 删除ceph残留文件
rm -rf /etc/ceph /etc/systemd/system/ceph* /var/lib/ceph/

# 重启服务器
sync; sync; sync; shutdown -r now

6. Ceph集群系统的性能相关参数与设置

使用Aliyun云服务器发邮件

默认情况下Aliyun云服务器对外25号端口被禁用了,需要申请解封,但不一定成功。此时,需要考虑使用邮箱的IMAP服务发送邮件。这需要邮箱服务器支持并启用IMAP服务。以下使用Aliyun服务器给QQ邮箱发送邮件为例:

1. 开启QQ邮箱的IMAP服务。

登录QQ邮箱后,在设置——帐户界面开启IMAP服务。若是已经开启,则可以点击关闭IMAP功能后再点击启用,此时需要使用密保手机发送指定内容短信到指定号码,则获得16个字符长度的授权码,后续会用到此授权码。

可以查看IMAP相关说明,获取IMAP服务的发送邮件服务器信息:

发送邮件服务器:smtp.qq.com
SSL端口号:465或587
账户名:您的QQ邮箱账户名(chenllianfu@foxmail.com)

2. 设置SSL证书

# 准备一个目录,用于存放证书信息
mkdir ~/.certs
cd ~/.certs

# 向qq邮箱请求SSL证书
date | openssl s_client -connect smtp.qq.com:465 | perl -e 'while (<>) { $keep = 1 if m/BEGIN/; print if $keep == 1; $keep = 0 if m/END/; }' > smtp_qq.crt

# 安装证书导入工具
yum install -y nss-tools

# 将证书增到数据库中
certutil -A -n "GeoTrust SSL CA" -t "C,," -d ./ -i ./smtp_qq.crt
certutil -A -n "GeoTrust Global CA" -t "C,," -d ./ -i ./smtp_qq.crt
certutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu" -d ./ -i ./smtp_qq.crt 

# 列出目录中数据库中的证书
certutil -L -d ./

3. 对邮件发送客户端进行配置

修改发送邮件的配置文件/etc/mail.rc内容:

cat << EOF >> /etc/mail.rc
set ssl-verify=ignore                        # 启用证书
set nss-config-dir=/root/.certs              # 设置证书数据库路径
set from="chenllianfu@foxmail.com"           # 邮箱全名
set smtp="smtps://smtp.qq.com:465"           # 发送邮件服务器地址
set smtp-auth-user=chenllianfu@foxmail.com   # 邮箱账户名
set smtp-auth-password=xxxxxxxxxxxxxx        # 邮箱授权码(不是邮箱登录密码)
set smpt-auth=login                          # 登录SMPT服务用于发送邮件
EOF

4. 发送邮件

测试邮件发送:

date | mail -s test chenllianfu@foxmail.com

使用IMAP方法发送邮件,其实是直接通过密钥证书加密传输数据,通过配置文件设置用户名和授权码登录邮件服务器,然后直接使用邮件服务器进行邮件操作。所以最后操作的发件人是chenllianfu@foxmail.com用户自己,同时也实现了Aliyun服务器和邮件服务器的连接,以利于将Aliyun服务器的数据通过邮件服务器发送出去。

DOI文献编号的意义

我们经常在文献引用信息中看到DOI编号,能够快捷地通过该编号打开该文献网址。

DOI(Digital Object Identifier)是指数字对象唯一标识符,是一套通过符号来识别视频、报告或书籍等数字资源的机制。DOI码由前缀和后缀两部分组成,中间用符号 / 分割,并且前缀以符号 . 再分成两部分。

国际DOI组织是一个非营利性机构,提供了DOI网站(www.doi.org)用于解析DOI编码,转换到相应的数字资源网址。例如,若需要查询DOI编码为10.1038/srep41124的文献,则可以先打开DOI网站www.doi.org,再在网站的搜索栏中搜索该DOI编码,会直接转换到文献网址,或直接在浏览器中打开网址www.doi.org/10.1038/srep41124,也能直接转换到文献网址中。

可以看出,DOI网站能用于DOI编码的解析,将DOI编码直接转换到数字资源的网址,和DNS域名解析是类似的。

CentOS7系统使用小经验

1. 增大系统字体

若屏幕分辨率为4k,则系统画面字体很小,眼睛看着难受。可以:(1)在gnome桌面点击右上角,再点击扳手图标打开控制面板;(2)再在控制面板中点击Devices,在Display中选择200%的Scale,则可以将整体画面都放大一倍,则感觉正常。

若在windows系统中使用虚拟机进行操作时,重新全屏一次或分辨率重新调节一次后,画面又恢复到正常的小字体情况,较为不便。则采用字体放大方法:(1)依次点击Applications,Accessories,Tweaks,打开Tweaks软件;(2)在左侧栏点击Fonts,将Scaling Factor设置为2,即可将所有字体放大一倍,则感觉正常。

2. 常用系统快捷键

  • windows + 左箭头:将选中的窗口放大到左半屏(左半侧50%全屏);
  • windows + 右箭头:将选中的窗口放到到右半屏(右半侧50%全屏);
  • windows + PgUp:切换到上一个桌面;
  • windows + PgDn:切换到下一个桌面;
  • windows + Tab:切换到同桌面中的下一个窗口;
  • windows + `:切换到下一个相同软件的窗口;
  • PrtScr:全屏截屏,保存到家目录;
  • alt + PrtScr:对当前窗口截屏,保存到家目录;
  • ctrl + PrtScr:对当前窗口截屏,保存到内存以供粘贴;
  • shift + PrtScr:对指定区域截屏,保持到家目录。

3. 手动设置系统快捷键

打开控制面板,依次点击Devices,Keyboard,可以查看并修改各快捷键设置。我个人喜欢的设置:

  • windows + d:隐藏所有窗口;
  • ctrl + 1:切换到第一个窗口(使用左边的ctrl键和小键盘数字);
  • ctrl + 2:切换到第二个窗口;
  • ctrl + 3:切换到第三个窗口;
  • ctrl + 0:切换到第四个窗口;
  • alt + d:打开gnome-terminal终端软件(和ctrl + d退出较类似)。

4. 自动更新系统时间

在windows系统下使用CentOS虚拟机系统。由于经常休眠windows系统导致CentOS虚拟机中时间经常不正确,需要更新CentOS系统时间。使用root用户执行如下操作,能自动更新系统时间。

echo -e "*/5\t*\t*\t*\t*\t/sbin/ntpdate cn.pool.ntp.org" > /root/.crontab
crontab /root/.crontab

5. 一次性打开多个排列整齐的终端,并同时连接服务器

我个人喜欢一次性打开3个终端:屏幕左半屏(左侧50%面积区域)上下各一个终端,屏幕右半屏(右侧50%面积区域)一个终端。手工生成一个gnome-terminal配置文件:

[GNOME Terminal Configuration]
Version=1
CompatVersion=1
Windows=Window0;Window1;Window2;

[Window0]
Geometry=106x27+2+60
Terminals=Terminals0
[Terminals0]
Command=dell

[Window1]
Geometry=105x56+1925+60
Terminals=Terminal1
[Terminal1]
Command=dell

[Window2]
Geometry=106x28+2+1055
Terminals=Terminal2
[Terminal2]
Command=dell

使用如下命令即可一次性打开3个终端,并自动使用dell命令连接到戴尔服务器:

gnome-terminal --load-config=/home/chenlianfu/.terminal_open3

配置DELL MD3200存储服务器连接到多台主机

戴尔MD3200磁盘存储服务器仅支持DELL SAS硬盘。该存储服务器可以上12块3.5英寸SAS硬盘、2个电源和2个控制器。每个控制器含有一个阵列卡带2G缓存,支持4个SAS IN接口用于连接4台主机。每台MD3200机器上2个控制器,则可以同时连接8台主机。此外,每个控制器含有一个SAS OUT口,用于连接到MD1200磁盘柜的SAS IN接口,从而支持拓展多达96块SAS硬盘。

1. 硬件组装

我本次经验,是将12块4TB的DELL SAS盘插入到DELL MD3200存储服务器中。然后,分别在3台服务器主机的PCI-E插槽上分别插上一片SAS直通卡。每片SAS直通卡有两个SF8088的SAS接口。使用6根SAS线(SF8088-SF8088)将MD3200存储上的SAS IN口和3台服务器的3片SAS直通卡进行相连。

此外,需要注意每张SAS直通卡贴纸上的一个编号,推荐拍照留存,以备后续使用。

2. 对DELL MD3200进行磁盘阵列设置

在个人windows10系统的笔记本电脑上安装软件DELL_MDSS软件,并设置笔记本电脑的有线网卡IP地址为192.168.128.120,使之和MD3200控制器IP地址192.168.128.101的IP段一致。然后将笔记本电脑的有线网口和控制器的网卡用网线连接,再打开DELL的MDSM软件。若两者有线网卡在同一IP地址段,则能自动找到存储阵列。

推荐重命名自动找到的存储阵列,然后双击对其进行管理,启动阵列管理窗口。再先后进行两项设置(1)阵列设置;(2)主机映射。

2.1 阵列设置

首先将最后两块盘设置为热备盘,然后以RAID5方式将其余所有的10块盘组成阵列,并使用所有的空间创建一个分区。

2.2 主机映射

在保证DELL MD3200存储服务器和3台服务器主机都开机并连接好数据线后,重启所有的服务器主机,以利于MD3200存储能识别3片SAS直通卡。

在MDSM的整列卡管理窗口中,创建一个名为chenlianfu的主机组,然后在该主机组下依次添加6个主机名。每添加一个主机时,需要设置一个SAS直通卡的机器码(需要和SAS直通卡上的机器码对应)和别名。每片SAS直通卡有两个SAS口,有两个机器码,对应添加的2个主机名。

主机映射做好后,即允许6个指定的SAS口可以访问磁盘存储。然后重启3台服务器,此时在重启界面中,在检测到SAS直通卡的时候,应该会提示其SAS直通卡检测到虚拟磁盘。在进入系统后,则会增加 /dev/sdb 和 /dev/sdc 两个设备,分别对应SAS直通卡的两个SAS口。

3. 对服务器主机进行多路径设置

在/dev/sdb和/dev/sdc两个路径都同时指向了存储服务器。需要通过CentOS系统中的多路径方式对这两个路径进行设置,使数据能同时通过这两个路径进行传输,才能充分达到6Gbps的数据。。

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install *device-mapper-multipath*
yum install *kpartx*
yum install *scsi_dh_rdac*
yum install *scsi_dh*
yum install *scsi_id*
yum install *udev*
yum install *modutils*
yum install *iscsi-initiator-utils*

在三台服务器上使用root用户都进行如下操作:

multipath -v3

使用如上命令得到/dev/sdb的wwid编号,然后,生成/etc/multipath.conf文件,其内容为:

blacklist {
    devnode "^sda"
# Begin Dell MD Modification
	device {
		vendor  "*"
		product "Universal Xport"
	}
	device {
		vendor  "*"
		product "MD3000"
	}
	device {
		vendor  "*"
		product "MD3000i"
	}
	device {
		vendor  "*"
		product "Virtual Disk"
	}
# End Dell MD Modification
}
defaults {
    user_friendly_names yes
    path_grouping_policy multibus
    failback immediate
    no_path_retry fail
# Begin Dell MD Modification
	max_fds             8192
# End Dell MD Modification
}
multipaths {
    multipath {
        wwid 36d4ae52000ad3c1800000c755df2d836
        alias chenlianfu_md3200
        path_grouping_policy multibus
        path_checker tur
        path_selector "round-robin 0"
    }
}
# Begin Dell MD Modification
devices {
	device {
		vendor                "DELL"
		product               "MD32xxi"
		path_grouping_policy  multibus
		prio                  rdac
		polling_interval      5
		path_checker          rdac
		path_selector         "round-robin 0"
		hardware_handler      "1 rdac"
		failback              immediate
		features              "2 pg_init_retries 50"
		no_path_retry         30
		rr_min_io             100
		prio_callout          "/sbin/mpath_prio_rdac /dev/%n"
	}
	device {
		vendor                "DELL"
		product               "MD32xx"
		path_grouping_policy  multibus
		prio                  rdac
		polling_interval      5
		path_checker          rdac
		path_selector         "round-robin 0"
		hardware_handler      "1 rdac"
		failback              immediate
		features              "2 pg_init_retries 50"
		no_path_retry         30
		rr_min_io             100
		prio_callout          "/sbin/mpath_prio_rdac /dev/%n"
	}
	device {
		vendor                "DELL"
		product               "MD36xxi"
		path_grouping_policy  multibus
		prio                  rdac
		polling_interval      5
		path_checker          rdac
		path_selector         "round-robin 0"
		hardware_handler      "1 rdac"
		failback              immediate
		features              "2 pg_init_retries 50"
		no_path_retry         30
		rr_min_io             100
		prio_callout          "/sbin/mpath_prio_rdac /dev/%n"
	}
	device {
		vendor                "DELL"
		product               "MD36xxf"
		path_grouping_policy  multibus
		prio                  rdac
		polling_interval      5
		path_checker          rdac
		path_selector         "round-robin 0"
		hardware_handler      "1 rdac"
		failback              immediate
		features              "2 pg_init_retries 50"
		no_path_retry         30
		rr_min_io             100
		prio_callout          "/sbin/mpath_prio_rdac /dev/%n"
	}
	device {
		vendor                "DELL"
		product               "MD34xx"
		path_grouping_policy  multibus
		prio                  rdac
		polling_interval      5
		path_checker          rdac
		path_selector         "round-robin 0"
		hardware_handler      "1 rdac"
		failback              immediate
		features              "2 pg_init_retries 50"
		no_path_retry         30
		rr_min_io             100
		prio_callout          "/sbin/mpath_prio_rdac /dev/%n"
	}
	device {
		vendor                "DELL"
		product               "MD38xxf"
		path_grouping_policy  multibus
		prio                  rdac
		polling_interval      5
		path_checker          rdac
		path_selector         "round-robin 0"
		hardware_handler      "1 rdac"
		failback              immediate
		features              "2 pg_init_retries 50"
		no_path_retry         30
		rr_min_io             100
		prio_callout          "/sbin/mpath_prio_rdac /dev/%n"
	}
	device {
		vendor                "DELL"
		product               "MD38xxi"
		path_grouping_policy  multibus
		prio                  rdac
		polling_interval      5
		path_checker          rdac
		path_selector         "round-robin 0"
		hardware_handler      "1 rdac"
		failback              immediate
		features              "2 pg_init_retries 50"
		no_path_retry         30
		rr_min_io             100
		prio_callout          "/sbin/mpath_prio_rdac /dev/%n"
	}
}
# End Dell MD Modification

再启动multipath服务:

systemctl restart multipathd.service 
systemctl enable multipathd.service 

这时,就可以在 /dev/mapper/目录下看到相应的设备了,在进行分区挂载操作等:

mkdir /disks/md3200/
mount /dev/mapper/chenlianfu_md3200p1 /disks/md3200/

最后,可以在 /etc/fstab 中增加一行,进行开机自动挂载:

/dev/mapper/chenlianfu_md3200p1 /disks/md3200   xfs     defaults        0       0

使用nginx运行wordpress

apache和nginx都能搭建网页服务。apache更老牌,功能模块更多,运行更稳定;而nginx运行性能更高,内存消耗更少。 使用apache时,每一个连接请求都对应服务器上一个进程,而在nginx中,多个连接(多达上万个)仅对应服务器上一个进程。相比于apache支持不超过3000个连接请求,nginx能支持高并发连接,每秒最多的并发连接请求理论可以道道5万个。本问讲解在不影响apache情况下额外使用nginx运行wordpress网站。

1. 安装wordpress软件

目前wordpress官网不再对中国内陆提供软件的下载了。需要使用代理下载wordpress软件。此外,最新版本的wordpress需要较高版本的PHP软件,而CentOS6或CentOS7自带的PHP软件版本较低,推荐使用较低版本的wordpress软件,例如:5.1.3版本。

cd /home/chenlianfu
wget https://cn.wordpress.org/latest-zh_CN.tar.gz
tar zxf latest-zh_CN.tar.gz

注意不管是使用apache还是nginx运行wordpress,最终其实都是使用apache用户来对软件目录进行读取或写入。需要使用root用户修改权
相关权限:

usermod -aG chenlianfu apache
chmod 750 /home/chenlianfu
chown -R apache:chenlianfu /home/chenlianfu/wordpress/

2. 安装nginx和php-fpm软件

使用root权限安装nginx和php-frm软件,后者用于让nginx识别php文件。此外,在安装CentOS系统时使用最大化安装,默认安装上了相应的一些mysql和php软件等。

yum install nginx php-fpm

3. 启动php-fpm软件

/etc/init.d/php-fpm restart
chkconfig php-fpm on

需了解的时是,在php-fpm的配置文件/etc/php-fpm.d/www.conf中,默认指定的使用者依然是apache。

4. 修改nginx配置文件

在nginx的主配置文件/etc/nginx/nginx.conf中修改端口号为8088。在CentOS6中可能是修改配置文件/etc/nginx/conf.d/default.conf。

    listen 8088;
#listen 80 default_server;
#listen [::]:80 default_server;

再增加nginx对wordpress的配置文件/etc/nginx/conf.d/wordpress_chenlianfu.conf,其内容为:

server {
    listen 8088;
    server_name www.chenlianfu.com;
    root /home/chenlianfu/wordpress;
    access_log  /var/log/nginx/host.access.log  main;
    location / { 
        try_files $uri $uri/ /index.php?$args;  
        index  index.php;
    }   
    
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    } 
}

最后,启动php-fpm和nginx服务并设置开机自动启动:

/etc/init.d/nginx restart
chkconfig nginx on

此时,可以在网页上使用8088端口访问nginx运行的wordpress网站了。这需要在浏览器中输入www.chenlianfu.com:8088来访问网站(这使还需要购买该域名并指向服务器的IP地址),比较不方便。

5. 修改apache配置文件实现apache和nginx共用80端口

默认情况下nginx和apache都使用了80端口,形成了冲突。我一般优先使用apache构建网站,有利于对服务器中的文件夹在网页中以目录形式访问。nginx对目录访问的效果较差,访问时其网址最后面一定要加一个目录符号正斜线 / ,否则不能访问其目录。因此,我优先让apache占用80端口,而让nginx占用8088端口。从而两种建站方式同时支持。

为了让nginx的网站直接使用80端口访问,这时,只需要在apache配置文件中设置将对www.chenlianfu.com:80的访问自动转到www.chenlianfu.com:8088即可。在/etc/httpd/conf/httpd.conf最尾部添加信息:

<VirtualHost *:80>
ProxyPreserveHost On
ServerName www.chenlianfu.com
ProxyPass / http://127.0.0.1:8088/
ProxyPassReverse / htt://127.0.0.1:8088/
</VirtualHost>

以上配置信息表示,每当访问www.chenlianfu.com的80端口时,自动转到本地机器的8088端口,即使用nginx提供的网页服务了。从而实现apache和nginx共用80端口的效果了。然后重启apache服务:

/etc/init.d/httpd restart

若敢兴趣的话,其实也可以优先让nginx占用80端口,让apache软件占用8088端口,然后在nginx的配置文件中设置端口转发,实现两个软件对80端口的共用。修改配置文件/etc/nginx/nginx.conf实现端口转发:

location ~ /.*/ {
proxy_pass http://127.0.0.1:8088;
}

将以上信息添加到server { }块中。location能以这则表达式的方法对网址进行解析。上述 ~ / / 表示正则匹配,和perl类似;.* 表示匹配任意内容。因此,上述内容表示将任意网址都转到8088端口上。

搭建邮箱服务并批量化做多个邮箱帐号用于KAAS注释

在使用KAAS网页工具进行注释时,一个邮箱同一时刻仅允许计算一个任务。若需要同时对许多物种进行KAAS分析时,则需要多个邮箱帐号。

若在各公共平台上申请邮箱会比较麻烦。此外,每使用一个邮箱帐号去进行KAAS分析时,然后登录一个个邮箱确认提交任务和查看结果是很麻烦的。因此,我在我的Aliyun服务器上直接创建很多邮箱帐号,然后用这些帐号进行KAAS分析,KAAS返回的邮件统一转到我的个人帐号,再进行后续的提交和结果查询。

1. 在万网上购买域名并进行域名解析

我购买的域名是chenlianfu.com,并将该域名解析中的A指向我的Aliyun服务器的IP地址,将MX指向chenlianfu.com。从而能让邮件识别我的域名并发送到我的Aliyun服务器上。

2. 在Aliyun服务器上通过postfix启动邮箱服务

默认设置下,CentOS6系统自带postfix软件。首先,修改postfix的配置文件/etc/postfix/main.cf内容,需要修改的几行如下:

myhostname = chenlianfu.com  # 用于设置主机名,表示邮箱账户为linux系统用户后加 @chenlianfu.com 。
inet_interfaces = all # 能接受所有来源的邮件
#inet_interfaces = localhost # 关闭默认的设置,默认仅接收来源本机的邮件
mydestination = $myhostname, localhost.$mydomain, localhost, chenlianfu.com

然后,防火墙开放25号端口:

iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT
service iptables save
/etc/init.d/iptables restart

最后启动postfix服务,则CentOS6系统中的用户可以接收来自其余人发送的邮件了。

/etc/init.d/postfix restart

若需要查看或寄送邮件,则输入命令 mail 即可:

mail

3. 在Aliyun服务器上创建多个系统用户

使用root权限创建50个账户:

perl -e 'foreach (1..50) { $_ = '0' . $_ if length($_) == 1; print "um$_\n"; } ' > users.txt
for i in `cat users.txt`
do
    useradd $i
    echo '123456' | passwd --stdin $i
done

为了简单演示,以上创建的用户密码都为123456,这里不太推荐使用如此简单的密码。

同时,需要设置当邮件发送到这些用户时,会自动转发到我的常用帐号所对应的邮箱中。我在Aliyun服务器上的账号名称是chenlianfu,对应的邮箱名称为chenlianfu@chenlianfu.com。通过使用root权限修改配置文件/etc/aliases文件来实现邮件转发。

for i in `cat users.txt`
do
    echo "$i:    chenlianfu,$i"
done >> /etc/aliases

为了使配置文件/etc/aliases生效,重启postfix即可:

/etc/init.d/postfix restart

4. 现在,即可使用这50个账号了。

封禁一些IPs的SSH登录,保护服务器安全

登录服务器的root用户时,可能会收到如下提示:

There were 3225 failed login attempts since the last successful login.

这表示有很黑客在尝试用一些用户和密码登录服务器。为了保障服务器安全,则可以在日志文件/var/log/secure中查看攻击的IPs来源和其失败登录的次数。例如:

Invalid user neisius from 211.144.12.75 port 34041
Failed password for invalid user server from 219.94.99.133 port 15139 ssh2
pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=106.12.217.39

若某个IP次数很高,则将其IP信息添加到/etc/hosts.deny文件中进行封禁。例如,修改/etc/hosts.deny文件内容:

sshd:101.109.83.140
sshd:103.27.238.202
sshd:104.236.94.202
sshd:106.12.200.13
sshd:106.12.217.39
sshd:106.54.19.67
sshd:111.230.73.133
sshd:117.50.45.254
sshd:118.24.38.53
sshd:122.155.223.119

为了能自动地封禁IPs,编写名为IP_denied_for_ssh_security.pl的perl程序:

#! /usr/bin/perl
use strict;

my $usage = <<USAGE;
Usage:
    $0 <num>

    运行程序后,程序读取/var/log/secure文件中信息。若存在某个IP登录失败(含有Invalid user|Failed password|authentication failure等信息)次数超过指定的次数,则是需要封禁的IP。此外,程序再读取/etc/hosts.deny文件中的IP信息,得到所有需要封禁的IP。然后程序将这些IP信息全部写入到/etc/hosts.deny文件中进行封禁。
    程序需要以root权限运行,因为只有root权限才能读取/var/log/secure文件,对/etc/hosts.deny进行写入。
    程序运行完毕后,会清空/var/log/secure文件内容。

USAGE
if(@ARGV==0){die $usage}

open IN, "/var/log/secure" or die "Can not open file /var/log/secure, $!";
my %num;
while (<IN>) {
    if (m/Invalid user/ or m/Failed password/ or m/authentication failure/) {
        $num{$1} ++ if m/(\d+\.\d+\.\d+\.\d+)/;
    }
}
close IN;

my %deny;
my $deny_num = 0;
foreach (keys %num) {
    if ($num{$_} >= $ARGV[0]) {
        $deny{$_} = 1;
        $deny_num ++;
    }
}
print STDERR "$deny_num IPs were detected for blocking from file /var/log/secure.\n";

open IN, "/etc/hosts.deny" or die "Can not open file /etc/hosts.deny, $!";
while (<IN>) {
    $deny{$1} = 1 if m/(\d+\.\d+\.\d+\.\d+)/;
};
close IN;

open OUT, ">", "/etc/hosts.deny" or die "Can not create file /etc/hosts.deny, $!";
my $total_num = 0;
foreach (sort keys %deny) {
    print OUT "sshd:$_\n";
    $total_num ++;
}
close OUT;
print STDERR "Total $total_num IPs were banned by file /etc/hosts.deny for SSH security.\n";

open OUT, ">", "/var/log/secure" or die "Can not  create file /var/log/secure, $!";
close OUT;

使用root用户执行该perl程序,若登录失败次数>=3次,则封禁对应的IP。

IP_denied_for_ssh_security.pl 3

基因正选择分析原理

一、 正选择分析的目的:

  1. 两两基因的密码子序列进行比较,从而计算dN/dS,即omega(ω)值。若该值<1,则表示纯化选择;omega = 1,则中性进化;omega > 1,则正选择。若分析基因在两个物种中的序列,可以计算dN/dS的值,若omega > 1,即表明该基因在物种进化过程中,即由其祖先物种分化成这两个物种时,基因受到了正选择。对于两个物种/序列的正选择分析,比较简单。而实际情况中,要分析的物种数量很多,包含多个类群。这个时候的正选择分析相对复杂些。
  2. 对多个物种的基因序列进行正选择分析,若仍然按照两个物种时的要求,即分析该基因在物种进化中是否受到了正选择?这种结果可能不好说清楚。因为该基因可能在某一类群中序列很相似,其两两比较时,omega <= 1;而在另外一类群中两两比较时,很多时候omega > 1。最后软件可以从总体上给一个omega值,该值不可以拿来简单地评价该基因是否受到了正选择。所以,对多个物种进行正选择分析时,没法直接评价该基因是否受到了正选择。正选择只有在进行两两序列比较的时候,才能计算omega值,从而得到结果。
  3. 对基因在多个物种上的正选择分析,分析的目的则是:比较某个分枝上祖先节点和后裔节点(可以理解成,对无根树上某分枝两侧的两组物种进行比较,依然属于两两比较),从而计算该分枝的omega值。而在实际数据中,基因在不同的进化分枝上具有不同的omega值,同时在序列不同的位点也具有不同的omega值。目标分枝两侧的物种数量较多时,可以对序列上的每个位点进行omega值分析,从而鉴定正选择位点。所以,对基因在多个物种上的正选择分析,需要同时分析分析目标分枝的omega值和序列位点的omega值,从而判断基因是否受到正选择压。

二、使用PAM对基因进行正选择分析,有三种方法:

  1. PAML site model: 主要用于检测基因中的正选择位点。该方法分析时,认为进化树中各分枝的omega值是一致的,并比较两种模型:(1)模型m1是null model,认为所有位点的omega值<1或=1; (2)模型m2是正选择模型,存在omega <1、=1或> 1的位点。比较两个模型的似然值(lnL)差异,利用卡方检验(自由度为2)算出p值。若p值 < 0.05,则否定null model,认为存在正选择位点。此外,推荐采用比较模型m7和m8,它们将omega值分成了10类,其p值结果比上一种比较方法更宽松,能检测到更多的正选择基因。使用PAML site model方法能在整体水平上检测基因的正选择位点,而不能表明基因在某个进化分枝上是否受到正选择压。
  2. PAML branch-site model: 主要用于检测基因在某个进化枝上是否存在的正选择位点。该分析方法认为目标分化枝具有一个omega值,其它所有分枝具有一个相同的omega值,然后再检测正选择位点。同样对两种模型进行比较:(1)第一种模型为模型2,将omega值分成<1、=1、>1的三类,这和site model中的一样;(2)第二种模型和前者一致,只是将omega固定成1,作为null model。比较两种模型的似然差异,利用卡方检验(自由度为2)算p值(chi2命令算出的值除以2)。若p值< 0.05,则能通过Bayes Empirical Bayes (BEB)方法计算正选择位点的后验概率,若存在概率值 > 0.95正选择位点,则表示基因在目标分枝上受到正选择压。PAML软件在branch-site模式下,并不给出分枝上的omega值。这表示branch-site模式虽然考虑了目标分枝上具有不同的omega值,但仍然以分析位点上的omega为主。值得注意的是,在branch-site模式下可能检测到正选择位点,但在目标分枝上的omega值仍然可能低于1。可能软件作者基于这点考虑,就没有给出目标分枝上的omega值,以免影响一些人对正选择结果的判断。
  3. PAML branch model: 主要用于检测在某个分枝上,其omega值是否显著高于背景分枝,即基因在目标分枝上进化速度加快。该方法认为基因序列上所有位点的omega值是一致的,对两种模型进行比较:(1)第一种模型为null model,所有分枝具有相同的omega值;(2)第二种模型认为目标分枝具有一个omega值,其它所有分枝具有一个相同的omega值。比较两种模型的似然差异,利用卡方检验(自由度为1)算p值。若p值 <= 0.05,且目标分枝上的omega值高于背景值,则认为该基因为快速进化基因。一般情况下,该方法计算得到的p值会低于第二种方法的结果。

三、其它注意事项

Branch-site model相比于site model的优点是考虑了不同的分枝具有不同的选择压,即具有不同的omega值。该方法让目标分枝具有一个不同的omega值,并没有让所有分枝的omega值独立进行计算(理论上这样是最好的)。这样算法很复杂,程序运行非常非常消耗时间。但其实也没必要这样做,因为正选择分析其实是两条序列比较后,分析dN/dS,再找正选择位点,其分析结果就应该是某个分枝上基因是否受到正选择,在序列那个位点上受到正选择。

若在目标分枝上,其omega值小于1,但是却能找到正选择位点。即该基因在该分枝上的dN/dS < 1,但是在某些位点上,dN/dS > 1。那么该基因是否属于正选择基因?我认为:属于。之所以为正选择基因,主要是因为基因的个别位点或多个位点存在正选择。当只有个别位点受到正选择压时,而其它多个位点存在纯化选择时,可能导致整体上的omega值小于1。此时,该基因也应该是属于正选择基因。

四、参考文献中的正选择分析方法描述

Science文章(https://science.sciencemag.org/content/364/6446/eaav6202)中的正选择基因分析方法:To estimate the lineage-specific evolutionary rate for each branch, the Codeml program in the PAML package (version 4.8) (134) with the free-ratio model (model = 1) was run for each ortholog. Positive selection signals on genes along specific lineages were detected using the optimized branch-site model following the author’s recommendation. A likelihood ratio test (LRT) was conducted to compare a model that allowed sites to be under positive selection on the foreground branch with the null model in which sites could evolve either neutrally and under purifying selection.[ The p values were computed based on Chi-square statistics, and genes with p value less than 0.05 were treated as candidates that underwent positive selection. We identified PSGs at the ancestral branch of Ruminantia (table S22), the ancestral branch of Pecora (table S23), each ancestral family branch of Ruminantia (tableS24), and each ancestral subfamily branch of Bovidae (table S24). We also compared the dN/dS values of Ruminantia families with outgroup mammals (fig. S52).

Science文章(https://science.sciencemag.org/content/364/6446/eaav6202)中快速进化基因分析方法:The branch model in PAML was used, with the null model (model=0) assuming that all branches have been evolving at the same rate and the alternative model (model=2), allowing the foreground branch to evolve under a different rate. An LRT with df =1 was used to discriminate between alternative models for each ortholog in the gene set. Genes with a p value less than 0.05 and a higher ω value for the foreground than the background branches were considered as evolving with a significantly faster rate in the foreground branch.


https://journals.plos.org/plosntds/article?id=10.1371%2Fjournal.pntd.0007463文献中对正选择基因的分析方法:

A calculation of mutational rate ratio ω between two gene sequences was the basis for the positive selection analysis. The ω was calculated as a ratio of nonsynonymous to synonymous mutational rates. The ratio indicates negative purifying selection (0 < ω < 1), neutral evolution (ω = 1), and positive selection (ω > 1) [54]. A set of selected genes from complete genomes was tested relative to positive selection using the maximum likelihood method using the CODEML of the PAML software package [55]. PAML version 4 [56] and its user interface PAMLX [57] were used in our study. For each analyzed gene, its maximum likelihood phylogenetic tree was used as an input tree. The CODEML offers several different codon evolutionary models, and the statistical likelihood ratio test (LRT) was used to compare the codon evolutionary model to the null model. The Bayes empirical Bayes method (BEB) [58] was then used to evaluate the posterior probability of sites considered to have been positively selected.

The CODEML models could produce different results (i.e., a list of sites under positive selection) since they calculate different parameter estimates. Site models allow ω to vary in each site (codon) within the gene. Statistical testing was required for sites with ω > 1. Two pairs of models were predominantly used since their LRTs have low false-positive rates. M1a (nearly neutral evolution) was compared to M2a (positive selection) [58,59] and M7 (beta) was compared to M8 (beta & ω) [60]. Our preliminary testing found that the two model pairs gave the same or very similar results. Therefore we chose to use the M7-M8 model pair. The M7 model is a null model that allows 10 classes of sites with a ω beta-distribution within the interval 0 ≤ ω ≤ 1. Sites with ω > 1 are not allowed. The alternative M8 model adds an eleventh class of sites with ω > 1. Each site was tested to determine the class to which it belongs. The LRT compares twice the log-likelihood difference 2Δl = 2(l1-l0) between the M7 model (log likelihood value l0) and the M8 model (log likelihood value l1) to the χ2 distribution [61]. If the twice log-likelihood difference is above a critical χ2 value, then the null model is rejected, and the positive selection is statistically significant.

A considerable disadvantage of the site models is that ω was calculated as an average over all codons of the site. Therefore, the site models are not suitable for the data where ω also varies between lineages. In contrast, the branch-site models search for positive selection in sites and pre-specifies lineages where different rates of ω may occur [62]. Sequences of lineages are a priori divided into a group of foreground lineages where positive selection may occur and group of background lineages where only purifying selection or neutral evolution occurs. We used branch-site model A, which allows four classes of sites and different setups of foreground lineages to be tested depending on the gene phylogeny. In branch-site model A, all lineages under purifying selection with a low value of ω0 belong to site class 0. Weak purifying selection and neutral evolution with ω1 near to value 1 are allowed in site class 1. In site class 2a, a proportion of class 0 sites in foreground lineages is under positive selection with ω2 > 1. Similarly, site class 2b is a proportion of class 1 sites under positive selection with ω2 > 1. The null model for LRT has ω2 = 1. Critical values of LRT (2Δl) are 2.71 at 5% and 5.41 at 1% [63]. The posterior probabilities of suggested sites under positive selection were calculated using the BEB method.