#################################################################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.confglobal {
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.resresource 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 status1: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 stopumount /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-keygencp /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=ignorecrm(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# verifycrm(live)configure# commit
查看集群状态(发现资源都运行在主节点上)
[root@one packages]# crmcrm(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/nologintar 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 /datamfschunkserver start
Client编译安装
MFS客户端依赖于fuse
tar xf fuse-2.9.2.tar.gzcd 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/nologintar 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 #定义vippcs 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复制及代理。
安装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端
安装软件包
查看当前磁盘情况(将/dev/sdb2发布出去3GB)
[root@localhost yum.repos.d]# fdisk -lDisk /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>
启动服务
命令行方式配置
tgtadm --lld iscsi --mode logicalunit --op new --tid 2 --lun 1 --backing-store /dev/sdb2tgtadm --lld iscsi --mode target --op bind --tid 2 --initiator-address 192.168.1.0/24
部署各节点
安装软件包
确保个节点hosts文件和hostname为以下
[root@node3 ~]# cat /etc/hosts192.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.conflocking_type = 3
定义集群名称
ccs_tool create tcluster添加fence设备
ccs_tool addfence meatware fence_manual添加集群成员
ccs_tool addnode -v 1 -n 1 -f meatware node1.soulboy.comccs_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 startservice rgmanager start
查看各节点信息
[root@node3 ~]# ccs_tool lsnodeCluster 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.rpmservice iscsi start 启动服务
各节点客户端执行发现和登录操做
[root@localhost mydata]# iscsiadm -m discovery -t sendtargets -p 192.168.1.50192.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 ~]# pvsPV 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]# vgsVG #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 ~]# lvsLV 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,添加入卷组便可不在演示过程。
测试
节点二
/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/sdbpvcreate /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。
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/fstab192.168.1.30:/shared /tmp/nfs nfs defaults,_rnetdev 0 0
让mountd和quotad等进程监听在固定端口
vim /etc/sysconfig/nfsMOUNTD_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 vsftpdservice 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 启用匿名用户anonymouslocal_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/CAmkdir 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/sslcd /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 tlsssl_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-develyum -y groupinstall "Development Tools" "Development Libraries"
安装pam_mysql-0.7RC1
tar zxvf pam_mysql-0.7RC1.tar.gzcd pam_mysql-0.7RC1
./configure --with-mysql=/usr --with-opensslrpm包的mysql
make
make install
安装vsftpd
yum -y install vsftpd2、建立虚拟用户帐号
准备数据库及相关表,首先请确保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=0account 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 vuserchmod go+rx /var/ftproot
请确保/etc/vsftpd.conf中已经启用了如下选项
anonymous_enable=YESlocal_enable=YES
write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=NO
chroot_local_user=YES
修改成NO,验证不经过SSL
force_local_data_ssl=NOforce_local_logins_ssl=NO
然后添加如下选项
guest_enable=YES 启用来宾用户guest_username=vuser 来宾用户为
并确保pam_service_name选项的值以下所示
pam_service_name=vsftpd.mysql4、启动vsftpd服务并测试
启动服务
service vsftpd startchkconfig vsftpd on 自动启动
查看端口开启状况
netstat -tnlp |grep :21查看数据库
FTP客户端工具登陆验证pam是否生效
5、配置虚拟用户具备不一样的访问权限
为虚拟用户使用配置文件目录
vim /etc/vsftpd/vsftpd.confuser_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/bobanon_upload_enable=YES (配置文件中已经开启,这里不写也能够)
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
tom不能够上传
vim /etc/vsftpd/vusers_dir/tomanon_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
- var db = openDatabase(databasename,version,description,size)
- databasename:数据库名;
- version:数据库版本号,可不填;
- description:数据库描述;
- size:给数据库分配的空间大小;
二、使用第一步建立的数据库访问对象(如db)执行transaction方法,用来执行事务处理;
[javascript] view plaincopy
- db.transaction(function(tx)){
- //执行访问数据库的语句
- });
三、经过executeSql方法执行查询
[javascript] view plaincopy
- tx.executeSql(sqlQuery,[value1,value2..],dataHandler,errorHandler)
- sqlQuery:须要具体执行的sql语句,能够是create、select、update、delete;
- [value1,value2..]:sql语句中全部使用到的参数的数组,在executeSql方法中,将sql语句中所要使用的参数先用“?”代替,而后依次将这些参数组成数组放在第二个参数中;
- dataHandler:执行成功是调用的回调函数,经过该函数能够得到查询结果集;
- errorHandler:执行失败时调用的回调函数;
本文经过HTML5的数据库支持,从新实现一遍上篇文章中的通信录管理,待实现功能以下:
- 可建立联系人并保存到数据库中,联系人字段包括:姓名、手机号码、公司、建立时间;
- 列出当前已保存的全部联系人信息;
- 可删除特定联系人信息;
一样,先准备一个HTML页面,以下:
[html] view plaincopy
- <!DOCTYPE HTML>
- <html>
- <head>
- <meta charset="utf-8"/>
- <title>HTML5本地存储之本地数据库篇</title>
- <style>
- .addDiv{
- border: 2px dashed #ccc;
- width:400px;
- text-align:center;
- }
- </style>
- </head>
- <body onload="loadAll()">
- <div class="addDiv">
- <label for="user_name">姓名:</label>
- <input type="text" id="user_name" name="user_name" class="text"/>
- <br/>
- <label for="mobilephone">手机:</label>
- <input type="text" id="mobilephone" name="mobilephone"/>
- <br/>
- <label for="mobilephone">公司:</label>
- <input type="text" id="company" name="company"/>
- <br/>
- <input type="button" onclick="save()" value="新增记录"/>
- </div>
- <br/>
- <div id="list">
- </div>
- </body>
- </html>
界面展示以下:

要实现建立新联系人并存入数据库功能,须要以下简单的JS代码:
[javascript] view plaincopy
- //打开数据库
- var db = openDatabase('contactdb','','local database demo',204800);
- //保存数据
- function save(){
- var user_name = document.getElementById("user_name").value;
- var mobilephone = document.getElementById("mobilephone").value;
- var company = document.getElementById("company").value;
- //建立时间
- var time = new Date().getTime();
- db.transaction(function(tx){
- tx.executeSql('insert into contact values(?,?,?,?)',[user_name,mobilephone,company,time],onSuccess,onError);
- });
- }
- //sql语句执行成功后执行的回调函数
- function onSuccess(tx,rs){
- alert("操做成功");
- loadAll();
- }
- //sql语句执行失败后执行的回调函数
- function onError(tx,error){
- alert("操做失败,失败信息:"+ error.message);
- }
[javascript] view plaincopy
- //将全部存储在sqlLite数据库中的联系人所有取出来
- function loadAll(){
- var list = document.getElementById("list");
- db.transaction(function(tx){
- //若是数据表不存在,则建立数据表
- tx.executeSql('create table if not exists contact(name text,phone text,company text,createtime INTEGER)',[]);
- //查询全部联系人记录
- tx.executeSql('select * from contact',[],function(tx,rs){
- if(rs.rows.length>0){
- var result = "<table>";
- result += "<tr><th> 序号</th><th>姓名</th><th>手机</th><th>公 司</th><th>添加时间</th><th>操做</th></tr>";
- for(var i=0;i<rs.rows.length;i++){
- var row = rs.rows.item(i);
- //转换时间,并格式化输出
- var time = new Date();
- time.setTime(row.createtime);
- var timeStr = time.format("yyyy-MM-dd hh:mm:ss");
- //拼装一个表格的行节点
- 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>";
- }
- list.innerHTML = result;
- }else{
- list.innerHTML = "目前数据为空,赶忙开始加入联系人吧";
- }
- });
- });
- }
[javascript] view plaincopy
- Date.prototype.format = function(format)
- {
- var o = {
- "M+" : this.getMonth()+1, //month
- "d+" : this.getDate(), //day
- "h+" : this.getHours(), //hour
- "m+" : this.getMinutes(), //minute
- "s+" : this.getSeconds(), //second
- "q+" : Math.floor((this.getMonth()+3)/3), //quarter
- "S" : this.getMilliseconds() //millisecond
- }
- if(/(y+)/.test(format)) format=format.replace(RegExp.$1,
- (this.getFullYear()+"").substr(4 - RegExp.$1.length));
- for(var k in o)if(new RegExp("("+ k +")").test(format))
- format = format.replace(RegExp.$1,
- RegExp.$1.length==1 ? o[k] :
- ("00"+ o[k]).substr((""+ o[k]).length));
- return format;
- }
要实现具体某个联系人,需执行以下JS代码:
[javascript] view plaincopy
- //删除联系人信息
- function del(phone){
- db.transaction(function(tx){
- //注意这里须要显示的将传入的参数phone转变为字符串类型
- tx.executeSql('delete from contact where phone=?',[String(phone)],onSuccess,onError);
- });
- }
如上截图中的表格样式,可参考以下CSS代码:
[css] view plaincopy
- th {
- font: bold 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
- color: #4f6b72;
- border-right: 1px solid #C1DAD7;
- border-bottom: 1px solid #C1DAD7;
- border-top: 1px solid #C1DAD7;
- letter-spacing: 2px;
- text-transform: uppercase;
- text-align: left;
- padding: 6px 6px 6px 12px;
- }
- td {
- border-right: 1px solid #C9DAD7;
- border-bottom: 1px solid #C9DAD7;
- background: #fff;
- padding: 6px 6px 6px 12px;
- color: #4f6b72;
- }
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/
第八届中国西南国际煤矿及采矿技术装备展览会
Set模型,集装箱改变世界
集装箱改变世界,集装箱改变了航运的经济规律.并所以改变了全球的贸易流。若是没有集装箱.就不会有全球化,集装箱成为经济全球化的幕后推手,主要有如下三个特性:
一、标准化,减小货物中转及理货时间,提升货物运输效率,下降运输成本,海上集装箱船装卸、中转。(货柜车\火车\轮船)
二、规模化,按集装箱规格来进行业务周转,规模化做业运转,下降运做成本,提升效率。( 30吨、20吨、10吨)
三、模块化,外形方正,尺寸标准化,堆放、装卸、运输方便,功能单一化,无需再包装,节约成本。
平常会有不少场景应用集装箱模式来解决不少问题,能够先看看咱们常遇到的问题:
一、业务很是多,每一个业务的服务器数量都很大,...
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)。充分利用数据局部性,而且让对象存储变得“更智能”,这是预计会取得进步的一个领域。