大杂烩

实现MooseFS的高可用

#################################################################javascript

  • 开篇引题php

  • Distributed Replicated Block Devicecss

  • 部署MFShtml

  • 部署Corosync+Pacemaker前端

  • 故障模拟测试java

  • 补充和总结node

#################################################################mysql

 

开篇引题linux

 

   直接上图,有图有真相啊!此图是MFS网络组成和运行原理,先不说图中每种角色的做用(下文会有详细说明),直观信息告诉咱们客户端不管是读写请求都须要与MasterServer通讯,而图中MasterServer角色只有一个,所以单点故障的因素就显而易见了。解决MFS的单点故障正是本文的初衷,接下来就介绍如何利用多种技术解决MFS的单点故障,实现MasterServer的高可用。nginx

 

Distributed Replicated Block Device

   分布式复制块设备是Linux内核的存储层中的一个分布式存储系统,可利用DRBD在两台Linux服务器之间共享块设备、文件系统和数据,相似于一个网络RAID1的功能,内核中的DRBD模块监听特定套接字上,复制系统调用产生的写数据为副本并经过TCP协议发送至DRBD从节点,由于节点间磁盘设备每个数据位都是相同的,因此DRBD能够实现廉价块级别的数据共享。

   DRBD工做模型

       主从模型(primary/secondary),同一时刻只能有一个节点提供服务(不然会产生脑裂),从节点没法使用磁盘分区(挂载也不能够)。

       主主模型(primary/primary),须要借助于集群文件系统并启用分布式文件锁功能,并且写性能不会有提高.

   DRBD管理

       内核模块:drbd用户空间

       管理工具:drbdadm,drbdsetup,drbdmeta

   工做流程(默认模型是Sync)

       Async:副本交于本地TCP/IP协议栈就返回(性能最高)

       SemiSync:副本交对方TCP/IP协议栈就返回(折中方案)

       Sync:副本被secondary存储到磁盘中就返回(性能差)

   安装配置DRBD(drbd内核模块必须和内核版本彻底匹配)

rpm -ivh drbd-8.4.3-33.el6.x86_64.rpm drbd-kmdl-2.6.32-358.el6-8.4.3-33.el6.x86_64.rpm 

   主配置文件

[root@one packages]# cat /etc/drbd.conf 
# You can find an example in  /usr/share/doc/drbd.../drbd.conf.example 
include "drbd.d/global_common.conf"; 
include "drbd.d/*.res"; 

    全局配置文件

cat /etc/drbd.d/global_common.conf 
global { 
    usage-count yes; 
    # minor-count dialog-refresh disable-ip-verification 

common { 
    handlers { 
        pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f"; 
        pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f"; 
        local-io-error "/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f"; 
        # fence-peer "/usr/lib/drbd/crm-fence-peer.sh"; 
        # split-brain "/usr/lib/drbd/notify-split-brain.sh root"; 
        # out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root"; 
        # before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k"; 
        # after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh; 
    } 
    startup { 
        # wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb 
    } 
    options { 
        # cpu-mask on-no-data-accessible 
    } 
    disk { 
        on-io-error detach; 
        # size max-bio-bvecs on-io-error fencing disk-barrier disk-flushes 
        # disk-drain md-flushes resync-rate resync-after al-extents 
                # c-plan-ahead c-delay-target c-fill-target c-max-rate 
                # c-min-rate disk-timeout 
    } 
    net { 
        cram-hmac-alg "sha1"; 
        shared-secret "soulboy"; 
        # protocol timeout max-epoch-size max-buffers unplug-watermark 
        # connect-int ping-int sndbuf-size rcvbuf-size ko-count 
        # allow-two-primaries cram-hmac-alg shared-secret after-sb-0pri 
        # after-sb-1pri after-sb-2pri always-asbp rr-conflict 
        # ping-timeout data-integrity-alg tcp-cork on-congestion 
        # congestion-fill congestion-extents csums-alg verify-alg 
        # use-rle 
    } 
    syncer { 
        rate 1000M; 
    } 

   定义资源mfs

[root@one packages]# cat /etc/drbd.d/mydata.res 
resource mydata { 
    on one.soulboy.com { 
        device  /dev/drbd0; 
        disk    /dev/sdb2;     #大小要一致 
        address 192.168.1.61:7789; 
        meta-disk internal; 
    } 
    on two.soulboy.com { 
        device  /dev/drbd0; 
        disk    /dev/sdb1;     #大小要一致 
        address 192.168.1.62:7789; 
        meta-disk internal; 
    } 

resource mfs { 
    on one.soulboy.com { 
        device  /dev/drbd1; 
        disk    /dev/sdb3; 
        address 192.168.1.61:7788; 
        meta-disk internal; 
    } 
    on two.soulboy.com { 
        device  /dev/drbd1; 
        disk    /dev/sdb2; 
        address 192.168.1.62:7788; 
        meta-disk internal; 
    } 

   同步配置文件到从节点

scp /etc/drbd.d/* two.soulboy.com:/etc/drbd.d/ 

   初始化资源(分别在两个节点上执行)

drbdadm create-md mfs 

   启动资源(分别在两个节点上执行)

service drbd start 

   将某节点变为主节点(192.168.1.61为主节点)

drbdadm primary --force mydata 

   查看状态肯定同步完毕

[root@one packages]# service drbd status 
1:mfs     Connected  Primary/Secondary  UpToDate/UpToDate  C  /mfs     ext4 

   格式化文件系统(在主节点)

mke2fs -t ext4 /dev/drbd1 

   容许对方抢占(分别在两节点上执行)

drbdadm primary mfs 

   开机不要自动启动

chkconfig drbd off 

部署MFS

   MFS工做原理

       MFS文件系统可以实现RAID功能,节约成本,不逊色于专业的存储系统,能够实如今线扩容。

   MFS的四种角色

       MasterServer(元数据服务器):负责管理各个ChunkServer及调度文件读写,回收文件空间及恢复多节点拷贝。

       Metalogger(元数据日志服务器):负责备份管理服务器的变化日志文件。

       ChunkServer(数据存储服务器):真正存储用户数据的服务器,将文件切块相互同步,遵从MasterServer的调度为Client提供数据传输,Chunk节点数量越多,可靠性和MFS可用的磁盘空间就会越大。

       Client(客户端):客户端经过fuse内核接口远程管理服务器上所管理的数据存储服务器,和使用本地文件系统同样。

   安装配置元数据服务

mount /dev/drbd1 /mfs               #挂载drbd设备 
groupadd -g 1000 mfs                #两边节点的uid要统一 
useradd -u 1000 -g mfs -s /sbin/nologin mfs  #两边节点都须要建立 
mkdir -pv /mfs                      #主节点建立数据目录便可 
chown -R mfs.mfs /mfs               #两个节点修改目录属主和属组为mfs 
tar xf mfs-1.6.26.tar.gz 
cd mfs-1.6.26 
./configure --prefix=/mfs --with-default-user=mfs --with-default-group=mfs 
make && make install 
cp /mfs/etc/mfsmaster.cfg.dist  /mfs/etc/mfsmaster.cfg 
cp /mfs/etc/mfsexports.cfg.dist  /mfs/etc/mfsexports.cfg 
cp /mfs/var/mfs/metadata.mfs.empty  /mfs/var/mfs/metadata.mfs 

   主配置文件

vim /mfs/etc/mfsmaster.cfg 
    # WORKING_USER = mfs            #运行用户 
    # WORKING_GROUP = mfs           #运行组 
    # SYSLOG_IDENT = mfsmaster      #在syslog中标识本身 
    # LOCK_MEMORY = 0               #是否执行mlockall()以免mfsmaster进程溢出(默认为0) 
    # NICE_LEVEL = -19              #运行的优先级 
    # EXPORTS_FILENAME = /usr/local/mfs/etc/mfsexports.cfg   #目录控制文件路径 
    # TOPOLOGY_FILENAME = /usr/local/mfs/etc/mfstopology.cfg #拓扑类型文件路径 
    # DATA_PATH = /usr/local/mfs/var/mfs    #数据存放路径(changelog,sessions,stats) 
    # BACK_LOGS = 50                        #元数据的改变日志文件数量 
    # BACK_META_KEEP_PREVIOUS = 1           # 
    # REPLICATIONS_DELAY_INIT = 300         #延迟复制时间(300秒) 
    # REPLICATIONS_DELAY_DISCONNECT = 3600  #ChunkServer断开复制的延迟 
    # MATOML_LISTEN_HOST = *                #元数据日志服务器监听的IP地址(*表明任何IP) 
    # MATOML_LISTEN_PORT = 9419             #元数据日志服务器监听的端口地址(9419) 
    # MATOCS_LISTEN_HOST = *                #用于ChunkServer链接的IP地址(*表明任何IP) 
    # MATOCS_LISTEN_PORT = 9420             #用于ChunkServer链接的端口(9420) 
    # MATOCL_LISTEN_HOST = *                #用于客户端链接的地址 
    # MATOCL_LISTEN_PORT = 9421             #用于客户端链接的端口 
    # CHUNKS_LOOP_CPS = 100000        
    # CHUNKS_LOOP_TIME = 300                #Chunks回环频率 
    # CHUNKS_SOFT_DEL_LIMIT = 10      
    # CHUNKS_HARD_DEL_LIMIT = 25 
    # CHUNKS_WRITE_REP_LIMIT = 2            #在一个循环里复制到一个ChunkServer的最大Chunks数目 
    # CHUNKS_READ_REP_LIMIT = 10 
    # REJECT_OLD_CLIENTS = 0                #弹出低于1.6.0客户端的链接 

   目录挂载控制文件

vim /mfs/etc/mfsexports.cfg #分为三个部分,无需修改 
*                       .           rw 
*                       /           rw,alldirs,maproot=0 
客户端IP         被挂载目录       客户端拥有的权限 

   为MasterServer提供lsb格式启动脚本

cat /etc/init.d/mfsmaster 
# chkconfig: 345 91 10 
# description: mfs start. 
. /etc/rc.d/init.d/functions 
. /etc/sysconfig/network 
path="/mfs/sbin" 
[ "${NETWORKING}" = "no" ] && exit 0 
start() { 
$path/mfsmaster start 
$path/mfscgiserv start 

stop() { 
$path/mfsmaster stop 
$path/mfscgiserv start 

restart() { 
$path/mfsmaster restart 
$path/mfscgiserv restart 

status() { 
$path/mfsmaster test 
$path/mfscgiserv test 

case "$1" in 
start) 
     start 
     ;; 
stop) 
     stop 
     ;; 
restart) 
     restart 
     ;; 
status) 
     status 
     ;; 
 *) 
     echo $"Usage: $0 start|stop|restart|status" 
     exit 1 
     esac 
     exit 0 

   修改权限

chmod 755 /etc/init.d/mfsmaster 

   导出命令

echo 'export PATH=$PATH:/mfs/sbin' > /etc/profile.d/mfs.sh 
. /etc/profile.d/mfs.sh 

   同步启动脚本至从节点

scp -p /etc/init.d/mfsmaster two:/etc/init.d/ 

   关闭服务卸载drbd设备

service mfsmaster stop 
umount /dev/drbd1 

 

部署Corosync+Pacemaker

   Corosync是集群管理套件的一部分,它在传递信息的时候能够经过一个简单的配置文件来定义信息传递的方式和协议等,RHCS集群套件就是基于corosync实现。但corosync只提供了message layer的能力。集群的资源管理则须要Pacemaker,其管理接口有两个分别是crmsh和pcs。

   环境准备

       service NetworkManager stop

       时间同

       主机名称解析的结果等于uname -n

   安装(pacemaker做为corosync的插件运行)

yum install -y corosync pacemaker 

    资源管理器配置接口基于crmsh

yum install -y crmsh-1.2.6-4.el6.x86_64.rpm pssh-2.3.1-2.el6.x86_64.rpm 

   生成密钥

corosync-keygen 
cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf 

   配置文件

vim /etc/corosync/corosync.conf #添加pacemaker插件 
            compatibility: whitetank    #是否兼容0.8版本的corosync 
            totem {                     #用来定义集群节点心跳信息传递 
                version: 2              #版本号 
                secauth: on             #启用安全认证机制 
                threads: 0              #启用多少线程完成心跳信息传递 
                interface {                   #定义心跳信息传递的接口 
                    ringnumber: 0             #避免循环转发心跳信息 
                    bindnetaddr: 192.168.2.0  #指定网卡的网络地址 
                    mcastaddr: 226.194.61.21   #心跳信息使用的组播地址 
                    mcastport: 5405            #组播监听端口 
                    ttl: 1 
                } 
            } 
            logging {               #心跳信息层日志 
                fileline: off       # 
                to_stderr: no       #是否把错误信息发往屏幕 
                to_logfile: yes     #使用自定义日志文件logfile 
                to_syslog: no       #是否记录到系统日志 
                logfile: /var/log/cluster/corosync.log 
                debug: off          #调试功能 
                timestamp: on       #每次记录心跳信息是否记录时间戳 
                logger_subsys { 
                    subsys: AMF 
                    debug: off 
                } 
            } 
            amf { 
                mode: disabled 
            } 
            service {       #添加pacemaker插件 
                ver: 0 
                name: pacemaker 
            } 
            aisexec {       #可省略 
                user: root 
                group: root 
            } 

   复制配置文件到其余节点

scp -p /etc/corosync/corosync.conf /etc/corosync/authkey two.soulboy.com:/etc/corosync/ 

  分别在两节点启动corosync服务

service corosync start 

   使用crmsh接口定义drbd资源(忽略法定票数、禁用stonith设备)

crm(live)configure# property no-quorum-policy=ignore 
crm(live)configure# property stonith-enabled=false 

   定义原始资源

crm(live)configure# primitive mfs_drbd ocf:linbit:drbd params drbd_resource=mfs op monitor role=Master interval=10 timeout=20 op monitor role=Slave interval=20 timeout=20 op start timeout=240 op stop timeout=100   #定义drbd资源 
crm(live)configure# ms ms_mfs_drbd mfs_drbd meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"   #定义drbd的克隆资源、克隆属性 
crm(live)configure# primitive mfsstore ocf:heartbeat:Filesystem params device="/dev/drbd1" directory="/mfs" fstype="ext4" op monitor interval=40 timeout=40 op start timeout=60 op stop timeout=60   #定义本地挂载资源 
crm(live)configure# primitive mfsip ocf:heartbeat:IPaddr params ip="192.168.1.40" op monitor interval=20 timeout=20 on-fail=restart   #定义vip 
crm(live)configure# primitive mfsserver lsb:mfsmaster   #定义mfs服务 

   定义colocation约束(资源运行在同一个节点上的偏好)

crm(live)configure# colocation mfsstore_with_ms_mfs_drbd_master inf: mfsstore ms_mfs_drbd:Master   #挂载资源追随drbd主资源在一块儿 
crm(live)configure# colocation mfsserver_with_mfsstore inf: mfsserver mfsstore   #mfs服务追随挂载资源 
crm(live)configure# colocation mfsip_with_mfsserver inf: mfsip mfsserver   #vip追随mfs服务 

 定义资源组(若是定义了资源组就没有必要定义colocation约束了)

crm(live)configure# group ha_mfsservice mfsstore mfsserver mfsip   #本文没有这样作,但特此说明这样作也是能够的 

   定义order约束(资源启动和关闭的次序)  

crm(live)configure# order ms_mfs_drbd_before_mfsstore mandatory: ms_mfs_drbd:promote mfsstore:start   #节点上存在drbdMaster才能启动mystore服务 
crm(live)configure# order mfsstore_before_mfsserver mandatory: mfsstore:start mfsserver:start   #mystore服务启动才能启动mfs服务 
crm(live)configure# order mfsip_before_mfsserver mandatory: mfsip mfsserver   #vip启动才能启动mfs服务    

 定义location约束(资源对节点的倾向性)

location mfsservice_prefer_one ha_mfsservice 500: one.soulboy.com   #主节点从故障中回复是否能够将资源抢夺回来,本文没有这样作,特此说明这样作是能够完成资源抢占的。 

   检查语法并保存

crm(live)configure# verify 
crm(live)configure# commit 

   查看集群状态(发现资源都运行在主节点上)

[root@one packages]# crm 
crm(live)# status 
Online: [ one.soulboy.com two.soulboy.com ] 
Master/Slave Set: ms_mfs_drbd [mfs_drbd] 
     Masters: [ one.soulboy.com ] 
     Slaves:  [ two.soulboy.com ] 
mfsstore   (ocf::heartbeat:Filesystem):    Started one.soulboy.com 
mfsserver  (lsb:mfsmaster):                Started one.soulboy.com 
mfsip      (ocf::heartbeat:IPaddr):        Started one.soulboy.com 

  查看验证

[root@one ~]# drbd-overview               #drbd资源正常 
  1:mfs/0     Connected Primary/Secondary UpToDate/UpToDate C r----- /mfs    ext4 5.0G 142M 4.6G 3% 
[root@one ~]# service mfsmaster status       #mfs资源正常 
mfsmaster pid: 13966 
mfscgiserv pid:14158 
[root@one ~]# ip addr show  | grep 192.168.1.40  #vip资源正常 
    inet 192.168.1.40/24 brd 192.168.1.255 scope global secondary eth0 
[root@one ~]# ls /mfs               #挂载资源正常 
etc  lost+found  sbin  share  var 

故障模拟测试

   安装ChunkServer

useradd mfs -s /sbin/nologin 
tar xf mfs-1.6.26.tar.gz 
cd mfs-1.6.26 
./configure --prefix=/usr/local/mfs --with-default-user=mfs --with-default-group=mfs 
make && make install 
cp /usr/local/mfs/etc/mfschunkserver.cfg.dist /usr/local/mfs/etc/mfschunkserver.cfg 
cp /usr/local/mfs/etc/mfshdd.cfg.dist /usr/local/mfs/etc/mfshdd.cfg 

   主配置文件

vim /usr/local/mfs/etc/mfschunkserver.cfg 
# WORKING_USER = mfs 
# WORKING_GROUP = mfs 
# SYSLOG_IDENT = mfschunkserver 
# LOCK_MEMORY = 0 
# NICE_LEVEL = -19 
# DATA_PATH = /usr/local/mfs/var/mfs 
# MASTER_RECONNECTION_DELAY = 5 
# BIND_HOST = * 
MASTER_HOST = 192.168.1.40         #元数据服务器的地址 
MASTER_PORT = 9420                 #元数据服务器监听端口 
# MASTER_TIMEOUT = 60 
# CSSERV_LISTEN_HOST = * 
# CSSERV_LISTEN_PORT = 9422       #此端口用户和其余ChunkServer间复制数据 
# HDD_CONF_FILENAME = /usr/local/mfs/etc/mfshdd.cfg   #分配给MFS磁盘使用空间配置文件路径 
# HDD_TEST_FREQ = 10 
# LOCK_FILE = /var/run/mfs/mfschunkserver.lock 
# BACK_LOGS = 50 
# CSSERV_TIMEOUT = 5 

   磁盘空间配置文件

vim /usr/local/mfs/etc/mfshdd.cfg 
/data      #/data是一个MFS的分区,实例化为本机一个独立的磁盘挂载分区。 

   修改权限并启动服务

chown -R mfs:mfs /data 
mfschunkserver start 

   Client编译安装

   MFS客户端依赖于fuse

tar xf fuse-2.9.2.tar.gz 
cd fuse-2.9.2 
./configure 
make && make install 
vim /etc/profile     #在最后添加 
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH 
source /etc/profile   #即时生效 
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH 

   安装MFS客户端

useradd mfs -s /sbin/nologin 
tar xf mfs-1.6.26.tar.gz 
cd mfs-1.6.26 
./configure --prefix=/usr/local/mfs --with-default-user=mfs --with-default-group=mfs --enable-mfsmount 
make && make install 
modprobe fuse    #加载fuse到内核 

   挂载MFS文件系统

mkdir /webdata       #建立本地目录做为挂载点 
/usr/local/mfs/bin/mfsmount /webdata -H 192.168.1.40   #挂载MFS到本地/webdata目录 

   挂载MFSMeta文件系统

mkdir /webdatameta   #建立本地MFSMeta目录 
/usr/local/mfs/bin/mfsmount -m /webdatameta -H 192.168.1.40   #挂载MFSMeta文件系统 

   client建立文件并查看信息(正常)

[root@five /]# echo "123" > /webdata/one   #建立文件 
[root@five /]# mfsfileinfo  /webdata/one  #查看副本和存储节点 
/webdata/one: 
    chunk 0: 0000000000000006_00000001 / (id:6 ver:1) 
        copy 1: 192.168.1.50:9422 
        copy 2: 192.168.1.64:9422 

   登陆web管理控制台(正常)

   模拟主节点故障

crm(live)node# standby    #离线,等待几秒钟 
crm(live)node# online     #上线 
crm(live)node# cd         #回退 
crm(live)# status         #查看集群资源状态 
Online: [ one.soulboy.com two.soulboy.com ] 
Master/Slave Set: ms_mfs_drbd [mfs_drbd] 
     Masters: [ two.soulboy.com ] 
     Slaves: [ one.soulboy.com ] 
mfsstore   (ocf::heartbeat:Filesystem):    Started two.soulboy.com 
mfsserver  (lsb:mfsmaster):                Started two.soulboy.com 
mfsip      (ocf::heartbeat:IPaddr):        Started two.soulboy.com 

   client再次建立文件并查看副本数(正常)

[root@five /]# echo "123" > /webdata/two 
[root@five /]# mfsfileinfo  /webdata/two 
/webdata/two: 
    chunk 0: 0000000000000007_00000001 / (id:7 ver:1) 
        copy 1: 192.168.1.50:9422 
        copy 2: 192.168.1.64:9422 

   再次登陆web管理控制台(正常)

 

补充和总结

   解决MFS单点故障的主要思路是将MasterServer安装在drbd设备目录中,经过corosync+pacemaker将drbd、vip、mount、mfsmaster资源粘合在一块儿,并经过colocation和order的约束保证了资源间依赖关系和启动次序,此外mfsmaster的启动在pacemaker中定义为lsb风格RA,也就是形如/etc/init.d/目录下的sysv风格的脚本。值得一提的是pacemaker的管理接口,本文中使用的是crmsh,而pcs接口有着比crmsh更强大的功能,能够实现管理集群整个生命周期,支持节点的添加、移除、启动、关闭等操做。

   实现mysql的高可用也能够经过本文这种思路实现,具体步骤可参考本文,这里补充下pcs接口的用法,方便读者作对比。

pcs resource create myvip ocf:heartbeat:IPaddr params ip=192.168.1.70 op monitor interval=20 timeout=20 on-fail=restart   #定义vip 
pcs resource create mystore ocf:heartbeat:Filesystem params device="192.168.1.50:/mysqldata" directory="/mydata" fstype="nfs" op monitor interval=40 timeout=40 on-fail=restart op start timeout=60 op stop timeout=60   #定义nfs 
pcs resource create mysqlserver lsb:mysqld op monitor interval=20 timeout=20 on-fail=restart   #定义httpd 
pcs resource group add mysqlservice myvip mystore mysqlserver   #定义webservice资源组 
pcs constraint location mysqlservice prefers two.soulboy.com=500   #定义资源倾向性,资源组webservice对节点二的倾向性为500 
pcs constraint order start myvip then start mystore   #定义资源的order执行次序,这个貌似不能一会儿定义三个资源月约束 
pcs constraint order start mystore then start mysqlserver   #定义资源的order执行次序 
pcs constraint colocation add myvip mystore   #定义colocation,若是有资源组能够省略。这个貌似不能一次定义三个资源月约束 
pcs constraint colocation add mystore mysqlserver   #定义colocation 

   实现mfs的高可用也能够经过heartbeat+drbd来实现,思路和本文相似,已经大牛撰写,文章内容优质,请参考:  qzhijun的BLOG

 

 

海量小文件存储利器Mogilefs

#######################################################################

  • 数据存储的趋势和大数据带来的挑战

  • 分布式存储与CAP定理

  • 分布式存储文件系统

  • Mogilefs基本原理

  • Mogilefs实现

  • Nginx反向代理Tracker节点

#######################################################################

 

数据存储的趋势和大数据带来的挑战

       当下咱们处在一个互联网飞速发展的信息社会,在海量并发链接的驱动下天天所产生的数据量必然以几何方式增加,随着信息链接方式日益多样化,数据存储的结构也随着发生了变化。在这样的压力下使得人们不得不从新审视大量数据的存储所带来的挑战,例如:数据采集、数据存储、数据搜索、数据共享、数据传输、数据分析、数据可视化等一系列问题。

传统存储在面对海量数据存储表现出的力不从心已是不争的事实,例如:纵向扩展受阵列空间限制、横向扩展受交换设备限制、节点受文件系统限制。

       然而分布式存储的出如今必定程度上有效的缓解了这一问题,之因此称之为缓解是由于分布式存储在面对海量数据存储时也并不是十全十美毫无压力,依然存在的难点与挑战例如:节点间通讯、数据存储、数据空间平衡、容错、文件系统支持等一系列问题仍处在不断摸索和完善中。

 

分布式存储与CAP定理

       首先要说明的是一个完美分布式系统有三个最重要的元素,他们分别是:

       一致性(Consistency):任何一个读操做老是能读取以前完成的写操做。

       可用性(Availability):每次操做老是可以在预约时间返回。

       分区容错性(Partition Tolerance):在出现网络分区(分布式)的状况下,仍然可以知足一致性和可用性。

       2007年,正当全部科学家都在致力于CAP三元素并存的时候,Eric.Brewer教授站了出来并指出CAP永远没法兼顾,只能根据具体应用来权衡和取舍,而且至多两个元素能够共存,后来由两位麻省理工学院的科学家证实此观点是具备前瞻性的,由此造成Brewer的CAP定理。

       正所谓鱼和熊掌不可兼得,关注一致性就须要处理因系统不可用而带来写操做失败的状况,反之关注可用性就没法保证每次都能读取到最新的写入操做。传统关系型数据库侧重于CA,而非关系型键值数据库则侧重于AP

       对于大型站点,可用性(Availability)分区容错性(Partition Tolerance)的优先级会高于一致性(Consistency),这里并非指彻底舍弃一致性,而是经过其余手段实现数据的弱一致性,例如:用户微博的浏览数和评论能够容忍相对长时间的不一致,几乎不会影响用户体验,而股票价格的数据则异常敏感,即使是10秒钟的数据不一致也没法容忍,为了能更形象的了解所谓“各类一致性”须要进行一下内容的回顾。

       强一致性(ACID)在单机环境中,强一致性能够由数据库的事务来保证;在分布式环境中,强一致性很难作到,即使是作到也会由于分布式事物所带来的性能低下,不适合在互联网的环境中应用。

       弱一致性(包括最终一致性)系统不能保证后续访问返回最新的值,在访问到最新值以前这段时间称之为不一致窗口

       最终一致性:是弱一致性的一种特例,存储系统保证若是对象有屡次更新,在渡过不一致窗口以后必将放回最后更新的值。

       服务器的一致性N表明节点的个数;W表明更新的时候须要确认已经被更新的节点个数;R表明读取数据须要的节点数量。

               W + R > N  ---->  强一致性(一般N=3,W=R=2)

               W=N,R=1   ---->  最佳读

               W=1,R=N   ---->  最佳写

               W + R <= N ---->  弱一致性

 

分布式存储文件系统



Mogilefs基本原理

       MogileFS是一个开源的分布式文件系统,用于组建分布式文件集群,由LiveJournal旗下DangaInteractive公司开发,Danga团队开发了包括 Memcached、MogileFS、Perlbal等不错的开源项目:(注:Perlbal是一个强大的Perl写的反向代理服务器)。MogileFS是一个开源的分布式文件系统。主要特性包括:应用层的组件、无单点故障、自动文件复制、具备比RAID更好的可靠性、无需RAID支持等……核心角色以下:

       tracker节点:借助数据库保存各节点文件的元数据信息保存每一个域中全部键的存储位置分布,方便检索定位数据位置的同时监控各节点,告诉客户端存储区位置并指挥storage节点复制数据副本,进程名为mogilefsd(7001)。

       database节点为tracker节点提供数据存取服务。

       storage节点:将指定域中的键转换为其特有的文件名存储在指定的设备文件中,转换后的文件名为值,storage节点自动维护键值的对应关系,storage节点因为使用http进行数据传输,所以依赖于perlbal,storage节点前端可使用nginx进行反向代理,但须要安装nginx-mogilefs-module-master模块进行名称转换,进程名mogstored(7501),perbal(7500)。

       Domain一个域中的键值是唯一的,一个MogileFS能够有多个域,域能够用来存储不一样应用类型的数据的容器。

       Host每个存储节点称为一个主机,一个主机上能够有多个存储设备(单独的硬盘),每一个设备都有ID号,Domain+Fid用来定位文件。

       Class:复制最小单位,文件属性管理,定义文件存储在不一样设备上份数。

       流程图以下:

       一、应用层发起GET请求到Nginx。

       二、Nginx根据负载均衡机制随机代理到后台Node one。

       三、Node one向从服务器发起查询请求。

       四、从服务器返回查询结果。

       五、Node one将查询结果返回给Nginx。

       六、Nginx将查询结果根据模块转换为合理的url方位Node three。

       七、Node Three将文件内容经过http协议返回给Nginx。

       八、Nginx将结果返回给应用层的请求。

 

Mogilefs实现

      因为各角色和服务之间都是基于套接字通讯,就服务自己来讲没有耦合性,因此可使用少许机器运行多种服务角色,功能图以下:

       一、经过Nginx+Keepalived实现高可用的负载均衡,经过upstream模块能够有选择性的转发应用层的请求至后端tracker节点。

       二、DRBD+Corosync+Pacemaker的机制保证了Mysql的高可用,详细配置请参阅博文:DAS之mysql高可用解决方案

       三、为了进一步提高Mysql的性能引入从节点为其分摊读操做,从节点的数据能够根据具体业务规模来设定,若是使用数据库代理进行读写分离,代理会成为单点故障,则须要为代理作高可用,另外Tracker节点支持手动为其指定从节点,所以能够根据本身的喜爱,Mysql代理和复制相关实现请参阅博文:Mysql复制及代理

##### Database节点 
安装mariadb 
受权 
GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY 'mypass'; 
CREATE DATABASE mogilefs; 
GRANT ALL ON mogilefs.* TO 'moguser'@'%' IDENTIFIED BY 'mogpass'; 
FLUSH PRIVILEGES; 
##### Tracker节点(能够是全部节点) 
安装 mogilefs 
修改配置文件以下 
vim /etc/mogilefs/mogilefsd.conf         
daemonize = 1 
pidfile = /var/run/mogilefsd/mogilefsd.pid 
db_dsn = DBI:mysql:mogilefs:host=192.168.1.241 
db_user = moguser 
db_pass = mogpass 
listen = 0.0.0.0:7001 
conf_port = 7001 
query_jobs = 100 
delete_jobs = 1 
replicate_jobs = 5 
reaper_jobs = 1 
service mogilefsd start     #启动服务 
ss -tanlp (LISTEN      0      128       192.168.1.241:7001  ) 
##### storage节点(能够是全部节点) 
安装 mogilefs 
mkdir /mogdata/dev1 -pv     #建立设备目录 
chown -R mogilefs.mogilefs /mogdata/dev2/   #权限 
vim /etc/mogilefs/mogstored.conf 
maxconns = 10000 
httplisten = 0.0.0.0:7500 
mgmtlisten = 0.0.0.0:7501 
docroot = /mogdata          #目录级别 
service mogstored start 
ss -tanlp (*:7500) 
##### tracker节点添加storage节点和经常使用命令 
mogadm check        #检测节点 
mogadm host list    #每一个存储节点称为一个host 
mogadm host add 192.168.1.213 --ip=192.168.1.213 --ip=192.168.1.213 --status=alive      #添加第一个存储节点 
mogadm host add 192.168.1.242 --ip=192.168.1.242 --ip=192.168.1.242 --status=alive       #添加第一个存储节点 
mogadm host add 192.168.1.241 --ip=192.168.1.241 --ip=192.168.1.241 --status=alive      #添加第一个存储节点 
mogadm device add 192.168.1.213 1    #添加第一个设备,设备号惟一不能重名 
mogadm device add 192.168.1.242 2   #添加第二个设备 
mogadm device add 192.168.1.241 3   #添加第三个设备 
mogadm check    #能够查看状态 
mogadm domain add files     #建立文件存储域 
mogadm domain add images    #建立图片存储域 
mogadm domain list  #查看全部域 
mogupload --trackers=192.168.1.241 --domain=files --key='/fstab' --file='/etc/fstab'     #上传fstab文件,key为'/fstab' 
mogfileinfo --trackers=192.168.1.241 --domain=files --key='/fstab'    #根据key查看文件存放信息 

注释:mogupload工具是为了测试,实际环境中上传是由程序员在代码中使用mogilefs的API进行交互。

 

Nginx反向代理Tracker节点

##### 配置Nginx 
安装tng 
yum install pcre-devel -y 
yum groupinstall "Development Tools" "Server Platform Development" 
yum install libxslt-devel gd-devel lua-devel geoip-devel 
tengine-1.5.1.tar.gz 
nginx-mogilefs-module-master.zip    #mogilefs模块须要打补丁 
mkdir -pv /var/tmp/nginx/client     #模块须要 
unzip nginx-mogilefs-module-master.zip 
useradd -r nginx 
./configure \ 
  --prefix=/usr/local/nginx \ 
  --sbin-path=/usr/local/nginx/sbin/nginx \ 
  --conf-path=/etc/nginx/nginx.conf \ 
  --error-log-path=/var/log/nginx/error.log \ 
  --http-log-path=/var/log/nginx/access.log \ 
  --pid-path=/var/run/nginx/nginx.pid  \ 
  --lock-path=/var/lock/nginx.lock \ 
  --user=nginx \ 
  --group=nginx \ 
  --enable-mods-shared=all \ 
  --add-module=/nginx-mogilefs-module-master 
make && make install 
vim /etc/profile.d/nginx.sh 
export PATH=/usr/local/nginx/sbin:$PATH 
. !$ 
提供脚本..... 
配置nginx 
vim /etc/nginx/nginx.cfg 
upstream trackers { 
        server 192.168.1.242:7001 weight=1; 
        server 192.168.1.213:7001 weight=1; 
        server 192.168.1.241:7001 backup; 
        check interval=3000 rise=2 fall=5 timeout=1000; 
        check_http_send "GET / HTTP/1.0\r\n\r\n"; 
        check_http_expect_alive http_2xx http_3xx; 
   } 
location /jpg/ { 
        mogilefs_tracker trackers; 
        mogilefs_domain images; 
        mogilefs_methods GET; 
        mogilefs_pass { 
            proxy_pass $mogilefs_path; 
            proxy_hide_header Content-Type; 
            proxy_buffering off; 
                } 
       } 
##### 配置keepalived 
安装keepalived 
vim /etc/keepalived/keepalived.conf  # backup  priority 99 
global_defs { 
   notification_email { 
     root@localhost 
   } 
   notification_email_from admin@localhost 
   smtp_server 127.0.0.1 
   smtp_connect_timeout 30 
   router_id LTT 

vrrp_script chk_nginx { 
   script "killall -0 nginx" 
   interval 1 
   weight -2 
   fall 2 
   rise 1 

vrrp_instance IN_1 { 
    state MASTER 
    interface eth0 
    virtual_router_id 22 
    priority 100 
    advert_int 1 
    authentication { 
        auth_type PASS 
        auth_pass aaaa 
    } 
    virtual_ipaddress { 
        192.168.1.222 
    } 
   track_script { 
    chk_nginx 


 

查看负载节点:

 

模拟GET方法测试Nginx_mogilefs模块:

 

 

SAN之可扩展的集群共享存储

###############################

SCSI

SAN

ISCSI

SAN和NAS的对比

ISCSI+gfs2+cLVM的实现

###############################

 

SCSI

计算机体系结构

  • CPU:核心组件,负责从memory中读取数据并进行处理。

  • Memory:核心组件,经过北桥与外围存储设备进行交换,做为易失性存储有极高的存储效率,但断电后数据会丢失。

  • IDE:有限的接口上,可以链接的设备有限,IDE的控制器在数据传输过程当中的协议封装能力不好,整个传输过程须要大量CPU时钟周期的参与,这就意味着CPU要花费大量的时候完成数据的读入和写出,在业务处理比较繁忙和CPU资源极尤其重要的场合下是没法忍受的。

  • SCSI:是一种I/O技术,SCSI规范了一种并行的I/O总线和相关的协议,除了硬盘转速上的提高外,总线的适配器HBA(HostBusAdapter)卡中内置了控制芯片,此控制芯片能够完成协议的封装,能够大量下降CPU的参与,此外因为SCSI的数据传输是以块的方式进行的,所以它具备如下特色设备无关性、多设备并行、高带宽、低系统开销

SCSI使用体系结构

  • 窄SCSI总线:最多容许8个SCSI设备和它进行链接。

  • 宽SCSI总线:最多容许16个不一样的SCSI设备和它进行链接

  • SCSI ID:一个独立的SCSI总线按照规格不一样能够支持8或16个SCSI设备,设备的编号须要经过SCSI ID(Target)来进行控制,系统中每一个SCSI设备都必须有本身惟一的SCSI ID,SCSI ID实际上就是这些设备的地址。

SCSI的局限性

  • 传输距离:因为SCSI线缆的长度有限,限制了SCSI的延展性。

  • 服务主机:Target数量限制了可服务的主机数。

 

 

SAN

  • 可以经过非SCSI线缆传输SCSI协议报文,而且能将其路由至目标存储设备的网络成为Storage Area Network(区域存储网络)。

 

SCSI协议报文

  • Physical Interconnects and Transport Protocols:定义物理传输介质和传输报文格式,经过光信道传输就成为FCSAN,经过IP网络传输就成为IPSAN

  • Shared Command Set:SCSI共享(公共)命令集,定义存储或读取等相关命令。

  • SCSI Device-Type Specific Command Sets:不一样SCSI设备类型特有的命令。

  • Common Access Method:公共访问方法。

 

ISCSI

IPSAN和FCSAN的对比

  • FCSAN:须要FC的HBA,存储端互相也须要FC的交换机或者SCSI线缆,应用程序存储数据由Adapter Driver向存储网络发起请求并完成数据存取。

  • IPSAN:应用程序的请求先交由SCSI驱动封装(协议报文各类指令),再由ISCSI驱动封装(用于联系ISCSI服务器端),借助于TCP/IP网络发送至ISCSI服务器端。

IPSAN的传输过程

  • ISCSI服务端:经过安装一款成熟的存储管理软件ISCSI Target,也称为Target。

  • ISCSI客户端:能够是硬件,也能够是安装iscsi客户端软,称为Initiator。客户端的链接方式有如下三种:

  • 以太网卡+initiator软件:成本低,但须要占用客户端主机部分资源用于ISCSI和TCP/IP协议之间的解析, 适用于低I/O带宽的环境下。

  • 硬件TOE网卡+initiator:TOE(TCP Offload Engine)功能的智能以太网卡能够完成ISCSI的封装,但SCSI封装仍以软件方式运做,使得客户端主机能够从繁忙的协议中解脱出来,大幅度提升数据传输速率,下降了客户端主机资源消耗。但TOE功能的网卡,成本较高。

  • ISCSI HBA卡链接:不须要安装客户端软件,所有靠硬件,数据传输性能最好,但成本很高,客户端数量和性价比成反比。

 

SAN和NAS的对比

注释:因为SAN是在DAS的基础之上增长了延展性,所以下图以DAS做比较:

结论:从图中能够看出NAS的文件系统在服务器端,而SAN的文件系统在客户端,由于SAN的客户端能够实现对分区的建立格式化等操做,而NAS不能够。所以SAN常常配合集群文件系统(gfs二、ocfs)一块儿使用,为的就是避免多个Initiator对Target的同一资源在同一时刻进行征用带来的脑裂。

 

ISCSI+gfs2+cLVM的实现

架构图以下:

部署Target端

安装软件包

yum install scsi-target-utils 

查看当前磁盘情况(将/dev/sdb2发布出去3GB)

[root@localhost yum.repos.d]# fdisk -l 
Disk /dev/sdb: 21.4 GB, 21474836480 bytes 
255 heads, 63 sectors/track, 2610 cylinders 
Units = cylinders of 16065 * 512 = 8225280 bytes 
   Device Boot      Start         End      Blocks   Id  System 
/dev/sdb1               1        1217     9775521   83  Linux 
/dev/sdb2            1218        1583     2939895   83  Linux 

经常使用配置 

/etc/tgt/targets.conf   配置文件的方式来管理target 
/etc/sbin/tgt-admin     经过配置文件定义 
/usr/sbin/tgtadm        经过命令行的方式管来target 
service tgtd start      启动服务 

编辑配置文件vim /etc/tgt/targets.conf

<target iqn.2013-08.com.soulboy:sdb1> 
        backing-store /dev/sdb2 
        initator-address 192.168.1.0/24 
</target> 

启动服务

service tgtd start 

命令行方式配置

tgtadm --lld iscsi --mode logicalunit --op new --tid 2 --lun 1 --backing-store /dev/sdb2 
    tgtadm --lld iscsi --mode target --op bind --tid 2 --initiator-address 192.168.1.0/24 

部署各节点

安装软件包

yum install -y cman rgmanager gfs2-utils vm2-cluster 

确保个节点hosts文件和hostname为以下

[root@node3 ~]# cat /etc/hosts 
192.168.1.21    node1.soulboy.com node1 
192.168.1.22    node2.soulboy.com node2 
192.168.1.23    node3.soulboy.com node3 

各节点时间同步

ntpdate 192.168.1.101 

集群逻辑卷 cLVM共享存储作成LVM,借用HA的机制,让多个节点能够同时对一个卷发起管理操做。

vim /etc/lvm/lvm.conf 
locking_type = 3 

定义集群名称

ccs_tool create tcluster 

添加fence设备

ccs_tool addfence meatware fence_manual 

添加集群成员

ccs_tool addnode -v 1 -n 1 -f meatware node1.soulboy.com 
ccs_tool addnode -v 1 -n 2 -f meatware node2.soulboy.com 
ccs_tool addnode -v 1 -n 3 -f meatware node3.soulboy.com 

在各节点依次启动服务

service  cman  start                 
service  rgmanager start 

查看各节点信息

[root@node3 ~]#  ccs_tool lsnode 
Cluster name: tcluster, config_version: 7 
Nodename                        Votes Nodeid Fencetype 
node1.soulboy.com                  1    1 
node2.soulboy.com                  1    2 
node3.soulboy.com 

各节点安装initator配置并启动服务

yum --nogpgcheck localinstall iscsi-initiator-utils-6.2.0.872-16.el5.i386.rpm
service iscsi start 启动服务 

各节点客户端执行发现和登录操做

[root@localhost mydata]#  iscsiadm -m discovery -t sendtargets -p 192.168.1.50 
192.168.1.50:3260,1 iqn.2013-08.com.soulboy:sdb1 
192.168.1.50:3260,1 iqn.2013-08.com.soulboy:sdb2 
[root@localhost mydata]#  iscsiadm -m node -T iqn.2013-08.com.soulboy:sdb2 -p 192.168.1.50 -l 

在任意initator上对共享设备建立分区(各节点在本地识别成sdc)

fdisk /dev/sdc 

在其余节点上执行

partprobe /dev/sdb 

在节点三建立物理卷

[root@node3 ~]# pvcreate /dev/sdc 

在节点二使用pvs命令查看

[root@node2 ~]# pvs 
PV         VG         Fmt  Attr PSize  PFree 
/dev/sda2  VolGroup00 lvm2 a--  19.88G    0 
/dev/sdc              lvm2 a--   2.80G 2.80G 

在节点三建立建立卷组

[root@node3 ~]# vgcreate clustervg /dev/sdc 

在节点二使用vgs命令查看

[root@node2]# vgs 
  VG         #PV #LV #SN Attr   VSize  VFree 
  VolGroup00   1   2   0 wz--n- 19.88G      0 
  clustervg    1   1   0 wz--nc  2.80G  2.80G 

在节点二建立逻辑卷

[root@node2]# lvcreate -L 1G -n clusterlv clustervg 

在节点三使用lvs命令查看

[root@node3 ~]# lvs 
LV        VG         Attr   LSize  Origin Snap%  Move Log Copy%  Convert 
LogVol00  VolGroup00 -wi-ao 17.88G                               
LogVol01  VolGroup00 -wi-ao  2.00G                               
clusterlv clustervg  -wi-a-  1.00G 

在集群逻辑上使用集群文件系统(暂时先建立2个日志区域,加入两个节点)

mkfs.gfs2 -j 2 -p lock_dlm -t tcluster:lktb1 /dev/clustervg/clusterlv 

各节点建立/mydata目录

mkdir /mydata 

各节点挂载逻辑卷clustervg至本地/mydata目录中

mount -t gfs2 /dev/clustervg/clusterlv /mydata 

查看信息

[root@node3 ~]# gfs2_tool df /mydata 
/mydata: 
  SB lock proto = "lock_dlm" 
  SB lock table = "tcluster:lktb1" 
  SB ondisk format = 1801 
  SB multihost format = 1900 
  Block size = 4096 
  Journals = 2 
  Resource Groups = 8 
  Mounted lock proto = "lock_dlm" 
  Mounted lock table = "tcluster:lktb1" 
  Mounted host data = "jid=1:id=196610:first=0" 
  Journal number = 1 
  Lock module flags = 0 
  Local flocks = FALSE 
  Local caching = FALSE 
  Type           Total Blocks   Used Blocks    Free Blocks    use%    
  ------------------------------------------------------------------------ 
  data           524196         66195          458001         13% 
  inodes         458018         17             458001         0% 

补充

#####马上同步到磁盘 
gfs2_tool settune /mydata new_files_directio 1 
#####默认是60秒,日志刷新次数 
log_flush_secs = 60                    
#####扩展逻辑卷物理边界至2GB(能够指定选项,不指默认就是扩展所有) 
lvextend -L 2G /dev/clustervg/clusterlv 
mount -t gfs2 /dev/clustervg/clusterlv /mnt 
#####扩展逻辑卷逻辑编辑至2GB 
gfs2_grow /dev/clustervg/clusterlv 
#####磁盘检测命令 
fsck.gfs2 
#####冻结gfs文件系统(只能读,不能写) 
gfs2_tool freeze /mydata 
#####解冻,备份数据的时候能够用到。 
gfs2_tool unfreeze /mydata 
注释:扩展卷组须要iSCSI添加新的设备,和使用LVM同样建立PV,添加入卷组便可不在演示过程。 

测试

节点二

[root@node2 mydata]# pwd 
/mydata 
[root@node2 mydata]# ls 
[root@node2 mydata]# touch node2 
[root@node2 mydata]# ls 
node2 

节点三

[root@node3 mydata]# pwd 
/mydata 
[root@node3 mydata]# ls 
node2 
[root@node3 mydata]# rm -rf node2 

节点二

[root@node2 mydata]# pwd 
/mydata 
[root@node2 mydata]# ls

 

 

NAS之mysql高可用解决方案

###############################################

NAS

高可用集群

hearbeat v二、crm、NFS实现MySQL高可用集群

NFS做为共享存储所存在的问题

###############################################

 

NAS

  • (NetworkAttachedStorage):网络附属存储是一种将分布、独立的数据整合为大型、集中化管理的数据中心,以便于对不一样主机和应用服务器进行访问的技术。它经过网络交换机链接存储系统和服务器,创建专门用于数据存储的私有网络,用户经过TCP/IP协议访问数据,采用业界标准的文件共享协议如:NFS、HTTP、CIFS来实现基于文件级的数据共享,NAS存储使文件共享访问变的快捷方便,而且易增长存储空间。但NAS自己也有必定的局限性,它会受到网络带宽和网络拥堵的影响,在必定程度上限制了NAS的网络传输能力。

  • NAS的优势:NAS具有文件操做和管理系统,kernel的存在有效解决多个进程在同一时间对同一资源征用带来的数据崩溃(脑裂split-brain);NAS是共享与独享兼顾的数据存储池而且简单灵活建立成本不高。

  • NAS的缺点:NAS自己将会受到网络带宽和网络拥堵的影响;文件级别的数据共享在必定程度上会影响效率。

 

高可用集群

  • 高可用集群,英文原文为High Availability Cluster,简称HA Cluster,简单的说,集群(cluster)就是一组计算机,它们做为一个总体向用户提供一组网络资源。这些单个的计算机系统 就是集群的节点(node)。只有两个节点的高可用集群又称为双机热备,即便用两台服务器互相备份。当一台服务器出现故障时,可由另外一台服务器承担服务任务,从而在不须要人工干预的 状况下,自动保证系统能持续对外提供服务。双机热备只是高可用集群的一种,高可用集群系统更能够支持两个以上的节点,提供比双机热备更多、更高级的功能, 更能知足用户不断出现的需求变化,逻辑结构图以下:

  • ccm(Cluster Consensus Menbership Service):监听节点间心跳信息并计算整个集群的票数和收敛状态信息。

  • crmd(Cluster Resource Manager):集群资源管理器实现了资源的分配,资源分配的每一个动做都要经过crm来实现,是核心组建,每一个节点上的crm都维护一个cib用来定义资源特定的属性,哪些资源定义在同一个节点上。

  • cib(Cluster Infonation Base):集群信息基库是XML格式的配置文件,在内存中的一个XML格式的集群资源的配置文件。

  • lrmd(Local Resource Manager):本地资源管理器用来获取本地某个资源的状态,而且实现本地资源的管理。

  • pengine:PE、TE

  • PE(Policy Engine):策略引擎负责计算集群资源的粘性

  • TE(Transition Engine):事务引擎根据PE计算结果指挥节点进行资源转移

  • stonithd(Shoot The Other Node in the Head):切断故障节点电源。

Messagin Layer软件

  • heartbeat

  • corosync

  • cman

  • keepalived

  • ultramokey

Cluster Resource Manager Layer软件

  • crm

  • pacemaker

  • rgmanager

HA经常使用组合

  • heartbeat v2+crm

  • heartbeat v3+pacemaker

  • corosync+pacemaker

  • cman + rgmanager

  • keepalived+lvs

 

 

hearbeat v二、crm、NFS实现MySQL高可用集群

  • 网络结构图以下:

注释:节点1和节点2上运行着HA软件和mysql服务,数据目录在NFS服务器端/mydata目录下,经过HA软件的实时监控能够完成节点故障时资源的自动转移,对于客户端来讲VIP表征着mysql服务,并持久可用。

必备条件

  • 节点名称必须跟uname -n命令的执行结果一致

  • 节点名称和IP对应关系保存在/etc/hosts文件,不依赖于DNS

  • 各节点ssh互信通讯

  • 集群各节点时间须要同步

######修改各节点主机名 
hostname node1.soulboy.com 
vim /etc/sysconfig/network 
HOSTNAME=node1.soulboy.com 
######修改hosts文件 
vim /etc/hosts 
192.168.1.131   node1.soulboy.com       node1 
192.168.1.132   node2.soulboy.com       node2 
######各节点ssh互信,节点二再也不演示 
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' 
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.1.132 
######各节点时间同步,须要时间服务器配合crontab 
* */5 * * *  ntpdate 192.168.1.100 

部署HA软件

######各节点安装软件包 
yum --nogpgcheck localinstall heartbeat-2.1.4-9.el5.i386.rpm heartbeat-gui-2.1.4-9.el5.i386.rpm heartbeat-pils-2.1.4-10.el5.i386.rpm heartbeat-stonith-2.1.4-10.el5.i386.rpm libnet-1.1.4-3.el5.i386.rpm perl-MailTools-1.77-1.el5.noarch.rpm 
######各节点提供配置文件 
cp /usr/share/doc/heartbeat-2.1.4/{authkeys,ha.cf,haresources} /etc/ha.d/ 
chmod 600 /etc/ha.d/authkeys 
######修改密钥文件authkeys 
dd if=/dev/random count=1 bs=512 | md5sum   生成随机数 
vim /etc/ha.d/authkeys 
auth 1 
1 md5 b20f227f85d8f51f76f9feec992061ed 
######各节点修改核心配置文件 
vim /etc/ha.d/ha.cf 
mcast eth0 225.0.100.20 694 1 0   组播 
node    node1.soulboy.com 
node    node2.soulboy.com 
crm     respawn                 crm今后代替haresources,并实现CRM功能 
######复制node1秘钥文件到node2 
scp /etc/ha.d/authkeys node2:/etc/ha.d/ -P  复制到node2 
######各节点启动服务 
service hearbeat start 

部署NFS服务器

partprobe /dev/sdb 
pvcreate /dev/sdb1 
vgcreate myvg /dev/sdb1 
lvcreate -L 6G -n mydata myvg 
mke2fs -j /dev/myvg/mydata 
groupadd -g 3306 mysql     添加mysql用户组 
useradd -u 3306 -g mysql -s /sbin/nologin -M mysql 
mkdir /mydata              建立共享目录 
vim /etc/fstab             开机自动挂载 
/dev/myvg/mydata    /mydata    ext3    defaults    0  0 
mount -a                   挂载 
mkdir /mydata/data         建立数据目录 
chown -R mysql.mysql /mydata/data/     修改目录为mysql用户 
vim /etc/exports 
/mydata         192.168.1.0/24(no_root_squash,rw)   修改共享权限 
exportfs -arv 

部署mysql服务

######各节点中止heartbeat服务 
service heartbeat stop 
######建立mysql用户和组 
groupadd -g 3306 mysql 
useradd -g 3306 -u 3306 -s /sbin/nologin -M mysql 
mkdir /mydata 
mount 192.168.1.230:/mydata /mydata    挂载目录 
usermod -s /bin/bash mysql             测试是否可写 
su - mysql 
touch /mydata/data/a 
rm /mydata/data/a 
logout 
usermod -s /sbin/nologin mysql 
umount /mydata                         测试正常 
#####在节点一上安装mysql 
tar xf mysql-5.5.28-linux2.6-i686.tar.gz -C /usr/local/ 
ln -sv /usr/local/mysql-5.5.28-linux2.6-i686 /usr/local/mysql 
chown -R root:mysql /usr/local/mysql/* 
mount 192.168.1.230:/mydata /mydata     挂载NFS共享目录到本地mydata目录 
#####初始化mysql 
/usr/local/mysql                        切换目录 
scripts/mysql_install_db --user=mysql --datadir=/mydata/data/  初始化 
#####修改相关配置文件 
cp /usr/local/mysql/support-files/my-large.cnf  /etc/my.cnf 
vim /etc/my.cnf 
datadir = /mydata/data 
innodb_file_per_table = 1               表空间独立 
cp /usr/local/mysql/support-files/mysql.server  /etc/init.d/mysqld 
chkconfig --add mysqld 
chkconfig mysqld off                    禁止开机自启动 
service mysqld start                    启动服务 
/usr/local/mysql/bin/mysql              客户端工具 
######为Mysql受权远程用户 
/usr/local/mysql/bin/mysql 
mysql> GRANT ALL ON *.* to 'root'@'%' IDENTIFIED BY 'redhat'; 
mysql> FLUSH PRIVILEGES; 
mysql> create database testdb; 
mysql> use testdb 
mysql> create table student (id int unsigned not null auto_increment primary key, name char(20)); 
######中止服务卸载目录 
service mysqld stop                     关闭mysql服务 
umount /mydata                          卸载mydata目录 
######同步配置文件和启动脚本到node2 
cp /etc/my.cnf  node2:/etc/   
scp /etc/init.d/mysqld  node2:/etc/init.d/ 
######为node2建立/mydata目录 
mkdir /mydata 

使用crm定义资源

######配置GUI登录帐户密码 
passwd hacluster 
######打开GUI登录窗口(请确保链接DC) 
hb_gui & 

一、登录crm

二、定义资源组

三、定义VIP

四、定义NFS存储

五、定义mysql服务

六、启动资源组

七、查看资源已运行在node2上

八、使用客户端登录测试

模拟故障测试HA功能是否生效

一、资源组此时运行在node2节点,node1并没有任何资源,此时让node2变为standy。

二、crm显示全部资源已成功转移至node1

三、切换至node1端验证真实性

四、mysql客户端第二次查询

crm的补充(关于资源约束)

 

location: 资源对节点的倾向程度,同一节点全部资源(进程)之和。

caloation:资源间互斥性,两个资源倾向于在一块儿仍是分开。

order: 资源采起动做的次序。

 

NFS做为共享存储所存在的问题

  • 单点故障的问题显而易见

 

 

Network File System

#####################################

Local Procedure Call为开发带来的不便

Remote Procedure Call的引入

Network File System

NFS在LAMP架构下的应用

#####################################

Local Procedure Call为开发带来的不便

 本地两个进程或进程和内核之间调用函数完成某种功能的过程叫作本地过程调用。

Remote Procedure Call的引入

 远程过程调用,不一样主机上的两个进程直接依赖于二进制协议通讯,它是编程技术及协议,简化分布式应用程序的开发,它一种开发框架,在这种框架下,程序员开发程序无需再考虑网络报文的封装,有RPC底层机制负责完成,RPC自己只是一种协议,它的实现是Portmap。

Network File System

1、NFS简介

 和ext三、ext2等同样,也位于内核空间做为内核模块工做的,它基于RPC基础实现,不一样主机上的两个进程直接依赖于二进制协议通讯,它可让远程文件系统挂载到本地一个目录。nfs-utils是NFS的安装包,包含了三个主进程:

nfsd   (文件传输主进程)      固定端口为TCP/UDP 2049端口

mountd  (接收客户端挂载请求)    动态向portmap注册端口

quotad  (磁盘配额进程)       动态向portmap注册端口

 /etc/exports  主配置文件

注意:因为nfs是基于RCP协议实现,因此请确保portmap服务开启

2、NFS工做机制

3、NFS使用方法

文件系统导出属性

ro                 只读 
rw                 读写 
sync               同步 
async              异步 
root_squach        将root用户映射为来宾帐号 
no_root_squach     很是不安全,客户端管理员此时等于服务器端管理员权限。 
all_squash         把用户所有映射为来宾用户,最安全 
anonuid,anongid    指定映射的来宾帐号UID和GID 

 简单的经过映射用户ID来标识文件属主和属组,客户端只要有用户ID号跟服务器端同样,就能够具备相应权限,至关不安全,所以一般能够把一个目录或文件锁定为一个服务器端能控制的用户,而全部用户的权限等于此用户的权限,例如:

NFS服务端 
useradd-u 510 nfstest 
touch/shared/nfstest 
chownnfstest.nfstest /shared/nfstest 
vim /etc/exports                          修改主配置文件 
/shared192.168.1.0/24(rw,all_squash,anonuid=510,anongid=510) 
exportfs -ra 

客户端从新挂载并看结果

showmount命令

mount-t nfs 192.168.1.30:/shared/tmp/nfs    挂载远程NFS共享目录至本地 
showmount -a 192.168.1.30    显示NFS服务器全部文件系统挂载状况 
showmount -e 192.168.1.30    显示NFS服务器已被挂在的文件系统和客户端列表 
showmount -d 192.168.1.30    显示NFS服务器已被挂在的文件系统列表 

exportfs命令(无需重启服务让配置文件生效)

-a 
-r    从新导出 
-u    取消导出 
-v    显示过程 
-arv  从新导出配置文件内容 
-auv  (取消全部导出文件系统) 

开机自动挂载

vim /etc/fstab 
192.168.1.30:/shared    /tmp/nfs    nfs    defaults,_rnetdev    0    0 

让mountd和quotad等进程监听在固定端口

vim   /etc/sysconfig/nfs 
MOUNTD_PORT=892 
RQUOTAD_PORT=875 
LOCKD_TCPPORT=32803 
LOCKD_UDPPORT=32769 

NFS在LAMP架构下的应用

1、NFS服务器端

部署LAMP平台

##########################安装LAMP########################## 
yum installhttpd httpd-develhttpd                安装httpd 
yum installmysql mysql-server mysql-devel mysql  安装mysql 
yum installphp53 php53-mbstring php53-mysqlphp   安装php 
##########################httpd############################# 
#AddDefaultCharset UTF-8                          修改字符集 
unzip Discuz_X2.5_SC_GBK.zip                      加压论坛 
mvupload/* /var/www/html/                        发布论坛 
service httpd start                               启动服务 
##########################mysql############################# 
mysqladmin -uroot -p password 'redhat'            为数据库添加密码 
grant all privileges on *.* to root@'%'identified by 'redhat'; 
                                                  远程受权root 
service mysqld start                               启动服务 
##########################修改权限安装论坛################## 
cd/var/www/html 
chmod777 config/ data/ data/cache/data/avatar/data/plugindata/data/download/data/addonmd5/data/template/data/threadcache/data/attachment/data/attachment/album/data/attachment/forum/data/attachment/group/data/log/uc_client/data/cache/uc_server/data/uc_server/data/cache/uc_server/data/avatar/uc_server/data/backup/uc_server/data/logs/uc_server/data/tmp/uc_server/data/view/ 

启动NFS服务

service portmap status                            检测portmap服务 
vim /etc/exports                                  修改主配置文件 
/var/www/html   192.168.1.240(rw,no_root_squash) 
exportfs –ra                                      从新导出目 
service nfs start                                 启动nfs服务 

2、NFS客户端

###########################安装LAP平台########################## 
yum install httpd httpd-devel                            安装httpd 
yum install php53 php53-mbstring php53-mysql             安装php 
service httpd start                                      启动服务 
##########################NFS客户端############################# 
mount -t nfs 192.168.1.230:/var/www/html /var/www/html   挂载目录 
#AddDefaultCharset UTF-8                                 修改字符集 
service httpd start                                      启动服务 

3、测试

客户端使用浏览器访问192.168.1.240(NFS客户端)

客户端使用浏览器访问192.168.1.230(NFS服务端)

 

 

File Transfer Protocol

#####################################

FTP简介

vsftpd基本使用

明文传输带来的安全隐患

安全通讯方式

vsftpd + PAM + mysql实现虚拟用户

#####################################

FTP简介

   文件传输服务位于应用层,监听21/tcp端口,数据传输模式为自适应,没有交叉编码能力Mine,遵循原文件自己格式,基于TCP协议实现,它有两个链接,命令链接和数据链接,它的工做模式有两种,主动模式和被动模式。

主动模式

被动模式

 

vsftpd基本使用

特性

   文件服务权限等于文件系统权限和文件共享权限的交集

   支持虚拟用户

       家目录在/var/ftp目录下,/目录被锁定为其家目录

   支持匿名用户

   支持系统用户

       家目录目录在/home/username目录下,/目录没有锁定,能够切换 lcd

   支持基于PAM实现用户认证

安装

yum install vsftpd 
service vsftpd start 
chkconfig vsftpd on 
/etc/vsftpd                        配置文件 
/etc/init.d/vsftpd                 服务脚本 
/usr/sbin/vsftpd                   守护进程 
/etc/pam.d/*                       配置文件 
/lib/security                      认证模块 
/var/ftp                           文件目录,不容许除root用户以外的其余用户具备写权限 

经常使用选项

anonymous_enable=YES            启用匿名用户anonymous 
local_enable=YES                启用系统用户 
write_enable=YES                开启写入 
anon_upload_enable=YES          开启上传 
anon_mkdir_write_enable=YES     开启目录建立 
anon_other_write_enable=YES     开启其余写权限,例如delete等…… 
dirmessage_enable=YES           开启目录进入欢迎提示 
    vim /var/ftp/upload/.message      当用户切换到此目录时候会显示 
xferlog_enable=YES             开启传输日志 
xferlog_file=/var/log/vsftpd.log      定义传输日志存储位置和名称 
#chown_uploads=YES              是否开启修改用户上传以后修改用户属主 
#chown_username=whoever         修改成谁? 
#idle_session_timeout=600       命令链接超时时间 
#data_connection_timeout=120    数据链接超时时间 
#ascii_upload_enable=YES        文本模式上传 
#ascii_download_enable=YES      文本模式下载 
chroot_list_enable=YES          禁锢用户至本身家目录 
chroot_list_file=/etc/vsftpd/chroot_list经过用户列表禁锢那些用户 
#chroot_local_user=YES          禁锢全部用户至本身家目录,须要注释上面两项 
listen=YES                      vsftpd是否工做为一个独立守护进程类型; 
        独立守护进程适合于 (访问量大,在线时间长的服务) 
        瞬时守护进程 (访问量比较小,在线时间不长的服务) 
pam_service_name=vsftpd         基于pam的认证 
  /etc/vsftpd/ftpusers (文件中用户不能登陆,清空/etc/vsftpd/user_list后才真正由此文件控制) 
userlist_enable=YES            文件的用户不容许登陆(/etc/vsftpd/user_list) 
userlist_deny=NO               仅容许文件中的用户能够登陆(/etc/vsftpd/user_list) 
tcp_wrappers=YES 
max_clients                    最多容许几个IP访问 
max_per_ip                     一个IP最多几个请求 

举例:让匿名用户能够上传文件

anon_upload_enable=YES    开启 
mkdir /var/ftp/upload 
setfacl -m u:ftp:rwx /var/ftp/upload/ 
getfacl /var/ftp/upload/ 

 

明文传输带来的安全隐患

使用客户端链接FTP服务器

在服务器端使用tcpdum命令抓包

tcpdump -i eth0 -nn -X -vv tcp port 21 and ip host 192.168.1.30

 

安全通讯方式

ftps:ftp+ssl/tls

sftp:OpenSSH,SubSystem,sftp(SSH)

建立私有CA

cd /etc/pki/CA 
mkdir certs newcerts crl 
echo 01 > serial 
(umask 077;openssl genrsa -out private/cakey.pem 2048)建立私钥 
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650生成自签证书 

生成证书颁发请求并签署

mkdir  /etc/vsftpd/ssl 
cd /etc/vsftpd/ssl 
(umask 077; openssl genrsa -out vsftpd.key 2048;)  生成私钥 
openssl req -new -key vsftpd.key -out vsftpd.csr   生成证书颁发请求 
openssl ca -in vsftpd.csr -out vsftpd.crt          签署证书 

修改配置文件etc/vsftpd/vsftpd.conf支持ssl、tsl功能

# ssl or tls 
ssl_enable=YES 
ssl_sslv3=YES 
ssl_tlsv1=YES 
allow_anon_ssl=NO 
force_local_data_ssl=YES 
force_local_logins_ssl=YES 
rsa_cert_file=/etc/vsftpd/ssl/vsftpd.crt 
rsa_private_key_file=/etc/vsftpd/ssl/vsftpd.key 

客户端软件登录

本文中使用FlashFXP做为FTP客户端

点击链接

成功链接

在服务器端抓包发现是明文

tcpdump -i eth0 -nn -X -vv tcp port 21 and ip host 192.168.1.30

 

vsftpd + PAM + mysql实现虚拟用户

1、安装所须要程序

事先安装好开发环境和mysql数据库;

yum -y install mysql-server mysql-devel 
yum -y groupinstall "Development Tools" "Development Libraries" 

安装pam_mysql-0.7RC1

tar zxvf  pam_mysql-0.7RC1.tar.gz 
cd  pam_mysql-0.7RC1 
./configure --with-mysql=/usr --with-opensslrpm包的mysql 
make 
make install 

安装vsftpd

yum -y install vsftpd 

2、建立虚拟用户帐号

准备数据库及相关表,首先请确保mysql服务已经正常启动。然后,按须要创建存储虚拟用户的数据库便可,这里将其建立为vsftpd数据库。

mysql> create database vsftpd; 
mysql> grant select on vsftpd.* to vsftpd@localhost identified by 'vsftpd'; 
mysql> grant select on vsftpd.* to vsftpd@127.0.0.1 identified by 'vsftpd'; 
mysql> flush privileges; 
mysql> use vsftpd; 
mysql> create table users ( 
    -> id int AUTO_INCREMENT NOT NULL, 
    -> name char(20) binary NOT NULL, 
    -> password char(48) binary NOT NULL, 
    -> primary key(id) 
    -> ); 

添加测试的虚拟,用户pam_mysql的password()函数与MySQL的password()函数可能会有所不一样。

insert into users (name,password) value ('bob','123'),('tom','321'),('lucy','333'); 

3、配置vsftpd

创建pam认证所需文件vi /etc/pam.d/vsftpd.mysql

auth required /usr/lib/security/pam_mysql.so user=vsftpd passwd=vsftpd host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=0 
account required /usr/lib/security/pam_mysql.so user=vsftpd passwd=vsftpd host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=0 

修改vsftpd的配置文件,使其适应mysql认证,创建虚拟用户映射的系统用户及对应的目录

useradd -s /sbin/nologin -d /var/ftproot vuser 
chmod go+rx /var/ftproot 

请确保/etc/vsftpd.conf中已经启用了如下选项

anonymous_enable=YES 
local_enable=YES 
write_enable=YES 
anon_upload_enable=YES 
anon_mkdir_write_enable=NO 
chroot_local_user=YES 

修改成NO,验证不经过SSL

force_local_data_ssl=NO 
force_local_logins_ssl=NO 

然后添加如下选项

guest_enable=YES        启用来宾用户 
guest_username=vuser    来宾用户为 

并确保pam_service_name选项的值以下所示

pam_service_name=vsftpd.mysql 

4、启动vsftpd服务并测试

启动服务

service vsftpd start 
chkconfig vsftpd on            自动启动 

查看端口开启状况

netstat -tnlp |grep :21 

查看数据库

FTP客户端工具登陆验证pam是否生效

5、配置虚拟用户具备不一样的访问权限

为虚拟用户使用配置文件目录

vim /etc/vsftpd/vsftpd.conf 
user_config_dir=/etc/vsftpd/vusers_dir 

建立所须要目录,并为虚拟用户提供配置文件

mkdir /etc/vsftpd/vusers_dir/ 
touch /etc/vsftpd/vusers_dir/bob /etc/vsftpd/vusers_dir/tom 

配置虚拟用户的访问权限;全部虚拟用户的家目录为/var/ftproot;全部的虚拟用户映射到vuser中,而vuser属于匿名用户,所以虚拟用户的访问权限是经过匿名用户指令生效的。

bob能够上传、建立、删除

vim /etc/vsftpd/vusers_dir/bob 
anon_upload_enable=YES      (配置文件中已经开启,这里不写也能够) 
anon_mkdir_write_enable=YES 
anon_other_write_enable=YES 

tom不能够上传

vim /etc/vsftpd/vusers_dir/tom 
anon_upload_enable=NO 

lucy能够上传

主配置文件中匿名上传已启用anon_upload_enable=YES,因此不须要作任何修改 

bob测试

tom测试

lucy测试

 

rsync+inotify搭建实时同步系统

rsync简介

   rsync是Linux和UNIX系统下的文件同步和数据传输工具,它采用了“rsync”算法使一个客户机和远程文件服务器之间的文件同步,它不一样于cp和wget命令完整复制的局限性,它支持增量备份,所以文件传输效率高,于是同步时间很短,具体特性以下:

   一、能够镜像保存整个目录树和文件系统

   二、能够增量同步数据。文件传输效率高。

   三、能够保持原有文件的权限、时间等属性。

   四、加密传输数据,保证数据的安全性。

   五、可使用rcp、ssh等方式来传输文件。

 

搭建远程容灾备份系统

   Web服务器为了保证数据安全,天天凌晨2点将数据备份到远程容灾服务器上,因为数据量比较大,每一年只能进行增量备份,仅备份当天新增数据,系统环境以下:

Web端配置

主配置文件/etc/rsyncd.conf

密码文件chmod 600 /etc/server.pass 

启动rsync守护进程

远程容灾端配置

密码文件chmod 600 /etc/server.pass

添加计划任务crontab -e

分析不足

此时一个远程容灾系统已经搭建完成,但这并不是是一个完整意义上的容灾方案,因为rsync须要经过触发才能将服务器端数据同步,所以两次触发同步的时间间隔内,服务器和客户端的数据可能不一致,若是在这个时间间隔内,网站系统出现问题,数据必然丢失,Linux 2.6.13之后的内核提供了inotify文件系统监控机制,用过rsync与inotify的组合,彻底能够实现rsync服务器端和客户端的实时数据同步。

 

rsync+inotify实现数据的实时备份

   inotify是一种强大的、细粒度的、异步的文件系统时间监控机制,Linux内核从2.6.13版本起,加入了对inotify的支持。经过inotify能够监控文件系统中添加、删除、修改、移动等各类细微事件,利用这个内核接口,第三方软件能够监控文件系统下文件的各类变化状况,inotify-tools软件正是基于这种需求实现的一个第三方软件。

   内容分发服务器实时同步数据对2个Web服务器上,inotify是用来监控文件系统变化的工具,所以必须安装在内容发布节点上,内容发布节点(Server)充当了rsync客户端的角色,2个Web节点充当了rsync服务器端的角色,整个数据同步过程就是一个从客户端向服务器端发送数据的过程,与前面案例中的逻辑结构恰好相反,系统环境以下:

Web1端配置

主配置文件/etc/rsyncd.conf

密码文件chmod 600 /etc/server.pass

启动rsync守护进程并添加开机自动启动

Web2端配置

主配置文件/etc/rsyncd.conf

密码文件chmod 600 /etc/server.pass

启动rsync守护进程并添加开机自动启动

Server端配置

安装inotify-tools

密码文件chmod 600 /etc/server.pass

监控目录变化并同步Web节点脚本

指定权限并放入后台运行

为此脚本添加开机自动启动

测试结果

Server端(rsync客户端)建立测试文件,如图:

Web1端查看,如图:

Web2端查看,如图:

 

 

HTML5本地存储之Database Storage篇

在上一篇《HTML5本地存储之Web Storage篇》中, 简单介绍了如何利用localStorage实现本地存储;实际上,除了sessionStorage和localStorage外,HTML5还支持通 过本地数据库进行本地数据存储,HTML5采用的是"SQLite"这种文件型数据库,该数据库多集中在嵌入式设备上,熟悉IOS/Android开发的 同窗,应该对SQLite数据库比较熟悉。

HTML5中的数据库操做比较简单,主要有以下两个函数:

一、经过openDatabase方法建立一个访问数据库的对象

[javascript] view plaincopy

  1. var db = openDatabase(databasename,version,description,size)  
该方法有四个参数,做用分别为:
  • databasename:数据库名;
  • version:数据库版本号,可不填;
  • description:数据库描述;
  • size:给数据库分配的空间大小;

二、使用第一步建立的数据库访问对象(如db)执行transaction方法,用来执行事务处理;

[javascript] view plaincopy

  1. db.transaction(function(tx)){  
  2.     //执行访问数据库的语句  
  3. });  
transaction方法使用一个回调函数做为参数,在这个函数中,执行访问数据库的具体操做;

三、经过executeSql方法执行查询

[javascript] view plaincopy

  1. tx.executeSql(sqlQuery,[value1,value2..],dataHandler,errorHandler)  
executeSql方法有四个参数,做用分别以下:
  • sqlQuery:须要具体执行的sql语句,能够是create、select、update、delete;
  • [value1,value2..]:sql语句中全部使用到的参数的数组,在executeSql方法中,将sql语句中所要使用的参数先用“?”代替,而后依次将这些参数组成数组放在第二个参数中;
  • dataHandler:执行成功是调用的回调函数,经过该函数能够得到查询结果集;
  • errorHandler:执行失败时调用的回调函数;

本文经过HTML5的数据库支持,从新实现一遍上篇文章中的通信录管理,待实现功能以下:

  • 可建立联系人并保存到数据库中,联系人字段包括:姓名、手机号码、公司、建立时间;
  • 列出当前已保存的全部联系人信息;
  • 可删除特定联系人信息;

一样,先准备一个HTML页面,以下:

[html] view plaincopy

  1. <!DOCTYPE HTML>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8"/>  
  5.     <title>HTML5本地存储之本地数据库篇</title>  
  6.     <style>  
  7.         .addDiv{  
  8.             border: 2px dashed #ccc;  
  9.             width:400px;  
  10.             text-align:center;  
  11.         }  
  12.     </style>  
  13. </head>  
  14. <body onload="loadAll()">  
  15.     <div class="addDiv">     
  16.         <label for="user_name">姓名:</label>  
  17.         <input type="text" id="user_name" name="user_name" class="text"/>  
  18.         <br/>  
  19.         <label for="mobilephone">手机:</label>  
  20.         <input type="text" id="mobilephone" name="mobilephone"/>  
  21.         <br/>  
  22.         <label for="mobilephone">公司:</label>  
  23.         <input type="text" id="company" name="company"/>  
  24.         <br/>  
  25.         <input type="button" onclick="save()" value="新增记录"/>  
  26.     </div>  
  27.     <br/>  
  28.     <div id="list">  
  29.     </div>  
  30. </body>  
  31. </html>  

界面展示以下:

 
要实现建立新联系人并存入数据库功能,须要以下简单的JS代码:

[javascript] view plaincopy

  1. //打开数据库  
  2. var db = openDatabase('contactdb','','local database demo',204800);  
  3.   
  4. //保存数据  
  5. function save(){  
  6.     var user_name = document.getElementById("user_name").value;  
  7.     var mobilephone = document.getElementById("mobilephone").value;  
  8.     var company = document.getElementById("company").value;  
  9.     //建立时间  
  10.     var time = new Date().getTime();  
  11.     db.transaction(function(tx){  
  12.         tx.executeSql('insert into contact values(?,?,?,?)',[user_name,mobilephone,company,time],onSuccess,onError);  
  13.     });  
  14. }  
  15.  //sql语句执行成功后执行的回调函数  
  16. function onSuccess(tx,rs){  
  17.     alert("操做成功");  
  18.     loadAll();  
  19. }  
  20. //sql语句执行失败后执行的回调函数  
  21. function onError(tx,error){  
  22.     alert("操做失败,失败信息:"+ error.message);  
  23. }  
要展示当前全部已保存的联系人列表,可经过以下JS代码实现:

[javascript] view plaincopy

  1. //将全部存储在sqlLite数据库中的联系人所有取出来  
  2. function loadAll(){  
  3.     var list = document.getElementById("list");  
  4.     db.transaction(function(tx){  
  5.         //若是数据表不存在,则建立数据表  
  6.         tx.executeSql('create table if not exists contact(name text,phone text,company text,createtime INTEGER)',[]);  
  7.         //查询全部联系人记录  
  8.         tx.executeSql('select * from contact',[],function(tx,rs){  
  9.            if(rs.rows.length>0){  
  10.                 var result = "<table>";  
  11.                 result += "<tr><th> 序号</th><th>姓名</th><th>手机</th><th>公 司</th><th>添加时间</th><th>操做</th></tr>";  
  12.                 for(var i=0;i<rs.rows.length;i++){  
  13.                     var row = rs.rows.item(i);  
  14.                     //转换时间,并格式化输出  
  15.                     var time = new Date();  
  16.                     time.setTime(row.createtime);  
  17.                     var timeStr = time.format("yyyy-MM-dd hh:mm:ss");  
  18.                     //拼装一个表格的行节点  
  19.                     result += "<tr><td>"+(i+1)+"</td><td>"+row.name+"</td><td>"+row.phone+"</td><td>"+row.company+"</td><td>"+timeStr+"</td><td><input type='button' value='删除' onclick='del("+row.phone+")'/></td></tr>";  
  20.                 }  
  21.                 list.innerHTML = result;  
  22.            }else{  
  23.                 list.innerHTML = "目前数据为空,赶忙开始加入联系人吧";  
  24.            }   
  25.         });  
  26.     });  
  27. }  
其中,涉及到格式化时间的format函数,可参考以下JS实现:

[javascript] view plaincopy

  1. Date.prototype.format = function(format)  
  2. {  
  3.     var o = {  
  4.     "M+" : this.getMonth()+1, //month  
  5.     "d+" : this.getDate(),    //day  
  6.     "h+" : this.getHours(),   //hour  
  7.     "m+" : this.getMinutes(), //minute  
  8.     "s+" : this.getSeconds(), //second  
  9.     "q+" : Math.floor((this.getMonth()+3)/3),  //quarter  
  10.     "S" : this.getMilliseconds() //millisecond  
  11.     }  
  12.     if(/(y+)/.test(format)) format=format.replace(RegExp.$1,  
  13.     (this.getFullYear()+"").substr(4 - RegExp.$1.length));  
  14.     for(var k in o)if(new RegExp("("+ k +")").test(format))  
  15.     format = format.replace(RegExp.$1,  
  16.     RegExp.$1.length==1 ? o[k] :  
  17.     ("00"+ o[k]).substr((""+ o[k]).length));  
  18.     return format;  
  19. }  
最后,界面实现效果以下:


要实现具体某个联系人,需执行以下JS代码:

[javascript] view plaincopy

  1. //删除联系人信息  
  2. function del(phone){  
  3.      db.transaction(function(tx){  
  4.         //注意这里须要显示的将传入的参数phone转变为字符串类型  
  5.         tx.executeSql('delete from contact where phone=?',[String(phone)],onSuccess,onError);  
  6.     });  
  7. }  

 

如上截图中的表格样式,可参考以下CSS代码:

[css] view plaincopy

  1. th {  
  2.     font: bold 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;  
  3.     color: #4f6b72;  
  4.     border-right: 1px solid #C1DAD7;  
  5.     border-bottom: 1px solid #C1DAD7;  
  6.     border-top: 1px solid #C1DAD7;  
  7.     letter-spacing: 2px;  
  8.     text-transform: uppercase;  
  9.     text-align: left;  
  10.     padding: 6px 6px 6px 12px;  
  11. }  
  12. td {  
  13.     border-right: 1px solid #C9DAD7;  
  14.     border-bottom: 1px solid #C9DAD7;  
  15.     background: #fff;  
  16.     padding: 6px 6px 6px 12px;  
  17.     color: #4f6b72;  
  18. }  
 
 
 
 
Anna

How to import merries diapers from Japan to China?

How to import merries diapers from Japan to China?

Seahog logistics firm can help you!

Chinese tax

Customs clearance

Customs declaration

Seahog Logistics is an international integrated logistics specialist business offering worldwide air freight and sea freight services to clients throughout the world. The company, which is located in Shanghai, was set-up in 1997 and has many years experience in the trade, with a global network of contacts and appointed agents.

 

Agent: Anna Leung   

Mobile: +86 15218771070

Tel: +86 769-89830090

Email: anna@seahog.cn 

anna0109@qq.com  

QQ:1975088296

Skype: AnnaLeung89

Company: Shanghai Seahog International Logistics Company

Address: Rm 404A, Building B, #1518 Minsheng Rd, Pudong New District,Shanghai City, China

Website: http://www.seahog-ay.com/  

 

 
 
 
 
磁选机安装

第八届中国西南国际煤矿及采矿技术装备展览会

第八届中国西南国际煤矿及采矿技术装备展览会_展会信息_财富云南_新浪七彩云南_新浪网 $(function () { $("#txtKeyword").focus(function () { if ($(this).val() == "输入你要搜索的关键字...") { $(this).val(""); } }); $("#txtKeyword").blur(function () { if ($(this).val() == "") { $(this).val("输入你要搜索的关键...
 
 
 
 
wyw5257

Set模型,集装箱改变世界

集装箱改变世界,集装箱改变了航运的经济规律.并所以改变了全球的贸易流。若是没有集装箱.就不会有全球化,集装箱成为经济全球化的幕后推手,主要有如下三个特性:

一、标准化,减小货物中转及理货时间,提升货物运输效率,下降运输成本,海上集装箱船装卸、中转。(货柜车\火车\轮船)
二、规模化,按集装箱规格来进行业务周转,规模化做业运转,下降运做成本,提升效率。( 30吨、20吨、10吨)
三、模块化,外形方正,尺寸标准化,堆放、装卸、运输方便,功能单一化,无需再包装,节约成本。

平常会有不少场景应用集装箱模式来解决不少问题,能够先看看咱们常遇到的问题:

一、业务很是多,每一个业务的服务器数量都很大,...

 
 
 
 
zjwsk

Hadoop分布式文件系统和OpenStack对象存储有何不一样

引用:http://blog.csdn.net/starean/article/details/11158979

 

“HDFS (Hadoop分布式文件系统)和OpenStack对象存储(OpenStack Object Storage)彷佛都有着类似的目的:实现冗余、快速、联网的存储。什么样的技术特性让这两种系统于是不同?这两种存储系统最终趋于融合是否大有意义?”

问题提出以后,很快有OpenStack的开发者进行了回复。本文在此摘抄了前两名回复进行翻译,以供各位参考。


排名第一的答案来自RackSpace的OpenStack Swift开发者Chuck Their:

虽然HDFS与Openstack对象存储(Swift)之间有着一些类似之处,可是这两种系统的整体设计却大不同。

1. HDFS使用了中央系统来维护文件元数据(Namenode,名称节点),而在Swift中,元数据呈分布式,跨集群复制。使用一种中央元数据系统对HDFS来讲无异于单一故障点,于是扩展到规模很是大的环境显得更困难。
2. Swift在设计时考虑到了多租户架构,而HDFS没有多租户架构这个概念。
3. HDFS针对更庞大的文件做了优化(这是处理数据时一般会出现的状况),Swift被设计成了能够存储任何大小的文件。
4. 在HDFS中,文件写入一次,并且每次只能有一个文件写入;而在Swift中,文件能够写入屡次;在并发操做环境下,以最近一次操做为准。
5. HDFS用Java来编写,而Swift用Python来编写。

 

另外,HDFS被设计成了能够存储数量中等的大文件,以支持数据处理,而Swift被设计成了一种比较通用的存储解决方案,可以可靠地存储数量很是多的大小不一的文件。

排名第二的答案来自Joshua McKenty,他是美国宇航局Nebula云计算项目的首席架构师,是OpenStack Nova软件的早期开发者之一,目前是OpenStack项目监管委员会的成员,仍是Piston.cc这家基于OpenStack的公司的创始人。

Chuck刚才详细介绍了二者的技术差别,可是没有讨论二者可想而知的融合,OpenStack设计峰会上抛出了融合这个话题。简而言之,HDFS被设计 成可使用Hadoop,跨存储环境里面的对象实现MapReduce处理。对于许多OpenStack公司(包括我本身的公司)来讲,支持Swift里 面的处理是路线图上面的一个目标,不过不是每一个人都认为MapReduce是解决之道。

咱们已讨论过为HDFS编写包装器,这将支持OpenStack内部存储应用编程接口(API),而且让用户能够针对该数据来执行Hadoop查询。还有一个办法就是在Swift里面使用HDFS。可是这些方法彷佛没有一个是理想的。

OpenStack社区方面也在开展研究开发方面的一些工做,认真研究其余替代性的MapReduce框架(Riak和CouchDB等)。

最后,如今有别的一些存储项目,目前“隶属于”OpenStack社区(SheepDog和HC2)。充分利用数据局部性,而且让对象存储变得“更智能”,这是预计会取得进步的一个领域。

相关文章
相关标签/搜索