1.1 分布式存储
集中式的数据存储比如SAN、NAS客户端访问存储时,都是通过存储服务器访问后端存储。存储本身会受到很多限制:
1、纵向扩展受阵列空间限制
2、横向扩展受交换设备限制
3、节点受文件系统限制
分布式存储无非是通过多个节点,每个节点提供一定量的存储空间。有一个节点作为整体的分发节点,来调度用户请求。该节点专门存放元数据,所以称为元数据服务器节点。当任何客户端想要存取数据时,通过网络向元数据服务器节点发起请求。当客户端想要存储某文件A时,首先检查该节点有没有A文件。
带宽受后端可用节点数量限制。存储数据时,分布式文件系统会将数据切割为大小固定的块chunk,每一个块都是一个独立的存储单元,所以就会出现第一个块在第一个主机上,第二个块在第二个主机上,等等这样的情况,看起来就像Raid0一样。同样的,如果其中一个节点挂了,整个所有的数据肯定就没了,这显然是不能够接受。这样一来,就只能在每个chunk在存储时存储双份,并把两份打散存储在不同的节点上。
元数据服务器节点不仅要记录文件的元数据,还要记录每个文件被切割成了多少个chunk、每一个chunk有多少个副本、每个副本存储在哪个主机上等等信息。并且还应该对该节点做高可用。为了使得客户端在访问的速度更快,元数据信息还会在内存中提供,那如何对内存中的数据进行冗余?可能需要开发专门的协议,这是非常麻烦的。有的分布式文件系统干脆直接将元数据信息放在共享磁盘上、还有的分布式文件系统通过数据库进行存放。
分布式文件系统还会面临节点存放数据不均衡的问题,一开始存储时都是平均的,但是数据不光会存储还会删除。时间久了,删除多了,就会存在不均衡的问题了。
chunk的分发不可避免的要用到一致性哈希算法。
一个分布式文件系统必须有机架感知能力,就是说两个副本不仅不能放在同一个节点上,还不应该放在同一个机架的节点上。避免多个节点使用的同一个交换机换了。
支持挂载称为分布式文件系统,不支持挂载称为分布式存储。数据库是一种存储,但也不支持挂载。
分布式文件系统满足三个特性:
1、可伸缩性
2、可靠性
3、总体成本消耗
开源搜索引擎解决方案:
Lucene, Sphinx
当前市面上分布式文件系统或存储:
GFS:Google File System,HDFS就是山寨GFS的,所以它们思路一致。
HDFS:Hadoop Distributed File System,适用于数量不太多的大文件场景。
namenode:名称节点,存储元数据,并且存放在内存中。
datanode:数据节点,存储数据。
TFS:Taobao FS,就是能够将元数据存储在第三方而非内存中的HDFS。将元数据存储于关系型数据库或其它高性能存储中,从而能维护海量文件元数据。
GlusterFS:去中心化的设计模式,没有元数据节点,每个节点既能存数据又能存元数据。越来越受到开源界重视。
ceph:Linux内核级实现的文件系统,而已经被直接收录进Linux内核。
MooseFS:又称为mfs,轻量级
MogileFS:轻量级
FastDFS:轻量级
1.1.1 MogileFS
三个组件:
tracker:追踪元数据
database:存储元数据
storage:存储数据
1.1.1.1 traker
可以将它想象成httpd服务器,通过restful风格将每一个文件访问的路径通过URL输出;而和storage节点打交道支持http、nfs两种协议;traker负责将storage节点的地址告诉客户端,由客户端去找storage;traker需要为整个系统的chunk维护2个以上的副本。
运行为mogilefsd(守护进程),它的主要职责包括:
1、 replication:节点间文件的复制
2、 deletion:删除文件
3、 queryworker:响应客户请求的文件元数据访问请求
4、 reaper:在存储失败后将文件复制请求重新放置于队列中,由traker再次进行调度。
5、 monitor:监测主机和设备的健康状态
1.1.1.2 database
存储mogilefs的元数据,一般使用MySQL;建议使用冗余方案以保证其可用性(MMM, MHA)。
mogilefs专门提供了数据结构管理工具mogdbsetup,使用mogdbsetup初始化数据库。
1.1.1.3 storage
mogstored(进程名),一个准备停当的mogstored节点可通过mogadm命令添加至现在的集群中。
存储节点需定义“设备(dev)”用作存储空间,每个“设备”在当前集群都需要通过一个惟一的DevID来标识。
client:
MogileFS专用的客户端工具,客户端用于与mogilefs建立通信,完成数据存取。
特性:
1、 工作于应用层,http, nfs。
2、 无单点
3、 自动完成文件复制
4、 传输无需特殊协议
5、 名称空间机制完成复制
6、 不共享任何数据,通过副本完成冗余。
1.1.1.4 两个关键术语
1、 domain:name space,命名空间,可以想象成一个domain就是一个目录。
一个MogileFS可以有多个domain,用来存档不同的文件,同一个domain内,文件肯定不能同名,而不同的domain就可以。所以说和目录一样。
2、 class:最小复制单元,为了方便进行管理,将多个文件组成一个class后一起做冗余。
MogileFS就是通过domain + Fid来追踪每个文件的,在domain中指明文件的id号来实现。
1.1.1.5 安装MogileFS
规划:web3为traker,web2、web4为storage
1、 安装
(1) 安装的组件
[[email protected] ~]# ll -rw-r--r-- 1 root root MogileFS-Server-2.46-2.el6.noarch.rpm -rw-r--r-- 1 root root MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm # traker -rw-r--r-- 1 root root MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm # storage -rw-r--r-- 1 root root MogileFS-Utils-2.19-1.el6.noarch.rpm -rw-r--r-- 1 root root perl-MogileFS-Client-1.14-1.el6.noarch.rpm -rw-r--r-- 1 root root perl-Net-Netmask-1.9015-8.el6.noarch.rpm -rw-r--r-- 1 root root perl-Perlbal-1.78-1.el6.noarch.rpm
(2) 安装
[[email protected] ~]# yum --nogpgcheck localinstall *.rpm
(3) 查看traker生成的组件
[[email protected] ~]# rpm -ql MogileFS-Server-mogilefsd /etc/mogilefs/mogilefsd.conf /etc/rc.d/init.d/mogilefsd /usr/bin/mogdbsetup # 数据库初始化工具 /usr/bin/mogilefsd # 守护进程对应的主文件
2、 授权root用户能够远程登陆,虽然数据库是本地,但还是当做远程来使用
MariaDB [(none)]> GRANT ALL ON *.* TO ‘root‘@‘172.16.%.%‘ IDENTIFIED BY ‘123456‘ WITH GRANT OPTION; MariaDB [(none)]> FLUSH PRIVILEGES; # WITH GRANT OPTION:自己获得的授权能够授予给其他用户
(1) 初始化数据库
[[email protected] ~]# mogdbsetup --dbhost=172.16.45.3 --dbrootuser=root --dbrootpass=123456 --dbname=mogdb --dbuser=moguser --dbpass=mogpass
(2) 编辑配置文件
[[email protected] ~]# cd /etc/mogilefs/ [[email protected] mogilefs]# cp mogilefsd.conf{,.bak} [[email protected] mogilefs]# vim mogilefsd.conf daemonize = 1 # 是否运行为守护进程 db_dsn = DBI:mysql:mogdb:host=172.16.45.3 # DBI:perl语言连接mysql的驱动 db_user = moguser db_pass = mogpass listen = 172.16.45.3:7001 query_jobs = 10 # 同时响应10个用户的请求 delete_jobs = 1 # 删除请求并发数 replicate_jobs = 5 # 复制请求并发数 reaper_jobs = 1 # 重新将请求给traker分配,无需修改
(3) 启动服务
[[email protected] mogilefs]# /etc/init.d/mogilefsd start
3、 另外两个storage节点
[[email protected] ~]# scp *.rpm 172.16.45.4:~ [[email protected] ~]# scp *.rpm 172.16.45.2:~ [[email protected] ~]# yum --nogpgcheck install *.rpm
(1) 安装storage依赖的一个包
[[email protected] ~]# yum install perl-IO-AIO
(2) 查看生成的文件
[[email protected] ~]# rpm -ql MogileFS-Server-mogstored /etc/mogilefs/mogstored.conf /etc/rc.d/init.d/mogstored /usr/bin/mogautomount # 自动挂载工具 /usr/bin/mogstored # 守护进程
(3) 修改配置文件
[[email protected] ~]# cd /etc/mogilefs/ [[email protected] mogilefs]# cp mogstored.conf{,.bak} [[email protected] mogilefs]# vim mogstored.conf maxconns = 10000 # 最大连接数 httplisten = 0.0.0.0:7500 # http协议 mgmtlisten = 0.0.0.0:7501 # 管理监听端口 docroot = /mogstore # 文件存储的目录
(4) 新建分区存储文件,并格式化后挂载
[[email protected] mogilefs]# fdisk /dev/sda [[email protected] mogilefs]# partx -a /dev/sda [[email protected] mogilefs]# mkdir /mogstore [[email protected] mogilefs]# mkfs -t ext4 /dev/sda3 [[email protected] mogilefs]# mount /dev/sda3 /mogstore/
(5) 在存储目录建立子目录,并且不能和其他节点同名
[[email protected] mogstore]# mkdir dev2 # 只能为 dev
(6) 改属主属组
[[email protected] mogstore]# chown -R mogilefs.mogilefs /mogstore/
(7) 启动服务
[[email protected] mogilefs]# /etc/init.d/mogstored start
4、 加入节点,在traker节点上进行
[[email protected] ~]# rpm -ql MogileFS-Utils # 通过此包完成 /usr/bin/mogadm # mogileFS管理工具 /usr/bin/mogdelete /usr/bin/mogfetch # 获取文件 /usr/bin/mogfiledebug /usr/bin/mogfileinfo # 查看文件 /usr/bin/moglistfids /usr/bin/moglistkeys /usr/bin/mogrename /usr/bin/mogstats /usr/bin/mogtool /usr/bin/mogupload # 上传
(1) 检查traker节点
[[email protected] ~]# mogadm --trackers=172.16.45.3:7001 check Checking trackers... 172.16.45.3:7001 ... OK Checking hosts... No devices found on tracker(s).
(2) 查看状态
[[email protected] ~]# mogstats --db_dsn="DBI:mysql:mogdb:host=172.16.45.3" --db_user="moguser" --db_pass="mogpass" --stats="all"
(3) 加入主机
[[email protected] ~]# mogadm --trackers=172.16.45.3:7001 host add 172.16.45.4 --ip=172.16.45.4 --status=alive [[email protected] ~]# mogadm --trackers=172.16.45.3:7001 host add 172.16.45.2 --ip=172.16.45.2 --status=alive
(4) 查看
[[email protected] ~]# mogadm --trackers=172.16.45.3:7001 host list 172.16.45.4 [1]: alive IP: 172.16.45.4:7500 172.16.45.2 [2]: alive IP: 172.16.45.2:7500
(5) 添加设备并查看
[[email protected] ~]# mogadm --trackers=172.16.45.3:7001 device add 172.16.45.4 2 [[email protected] ~]# mogadm --trackers=172.16.45.3:7001 device add 172.16.45.2 1 [[email protected] ~]# mogadm --trackers=172.16.45.3:7001 device list 172.16.45.4 [1]: alive used(G) free(G) total(G) weight(%) dev2: alive 0.042 27.866 27.908 100 172.16.45.2 [2]: alive used(G) free(G) total(G) weight(%) dev1: alive 0.527 17.595 18.122 100
(6) 定义名称空间,并查看
[[email protected] ~]# mogadm --trackers=172.16.45.3:7001 domain add images [[email protected] ~]# mogadm --trackers=172.16.45.3:7001 domain add conffiles [[email protected] ~]# mogadm --trackers=172.16.45.3:7001 domain list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- conffiles default 2 MultipleHosts() NONE images default 2 MultipleHosts() NONE # 会自动创建类 # mindevcount为2表示文件存储两个副本 # replpolicy为MultipleHosts()表示复制策略为多主机,副本不会放在同一主机 # class中文件记录时会做哈希计算,hashtype为none表示不做哈希计算
(7) 添加class并查看
[[email protected] ~]# mogadm --trackers=172.16.45.3:7001 class add images nc1 --mindevcount=2 [[email protected] ~]# mogadm --trackers=172.16.45.3:7001 class list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- conffiles default 2 MultipleHosts() NONE images default 2 MultipleHosts() NONE images nc1 2 MultipleHosts() NONE
5、 正式使用mogileFS
(1) 上传一个文件
[[email protected] ~]# mogupload --trackers=172.16.45.3:7001 --domain=images --key=‘1.jpg‘ --file=‘/usr/share/backgrounds/centos_1920x1200_logoonly.jpg‘ # --key指定的是URL,也就是访问路径
(2) 此时文件已经存储到后端节点了,查看文件的信息
[[email protected] ~]# mogfileinfo --trackers=172.16.45.3:7001 --domain=images --key=‘1.jpg‘ - file: 1.jpg class: default devcount: 2 domain: images fid: 2 key: 1.jpg length: 57592 - http://172.16.45.2:7500/dev1/0/000/000/0000000002.fid # 可以通过浏览器直接访问 - http://172.16.45.4:7500/dev2/0/000/000/0000000002.fid
(3) 将文件下载下来
[[email protected] ~]# mogfetch --trackers=172.16.45.3:7001 --domain=images --key=‘1.jpg‘ --file=‘/root/1.jpg‘
1.1.1.6 编译nginx mogilefs模块
1、 编译并配置
[[email protected] ~]# yum install -y pcre-devel [[email protected] ~]# tar xf nginx-1.6.2.tar.gz [[email protected] ~]# tar xf nginx_mogilefs_module-1.0.4.tar.gz [[email protected] ~]# cd nginx-1.6.2 [[email protected] nginx-1.6.2]# ./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 --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --add-module=../nginx_mogilefs_module-1.0.4 [[email protected] nginx-1.6.2]# make && make install
(1) 准备nginx启动脚本
[[email protected] ~]# vim /etc/init.d/nginx [[email protected] ~]# chmod +x /etc/init.d/nginx [[email protected] ~]# chkconfig --add nginx [[email protected] ~]# useradd -r nginx [[email protected] ~]# mkdir /var/tmp/nginx/{client,proxy,fcgi,uwsgi,scgi} –pv [[email protected] ~]# service nginx start
(2) 编辑配置文件
[[email protected] nginx]# vim nginx.conf location /images/ { mogilefs_tracker 172.16.45.3:7001; # 如果有多个tracker节点,可以将它们定义为一个upstream进行调用,还能进行负载均衡和后端健康状态监测 mogilefs_domain images; mogilefs_pass { proxy_pass $mogilefs_path; proxy_hide_header Content_Type; # 隐藏首部 proxy_buffering off; # 关闭缓冲 } } [[email protected] nginx]# service nginx reload
(3) 直接通过浏览器访问http://172.16.45.3/images/1.jpg
2、配置上传
(1) 编辑配置文件
[[email protected] nginx]# vim nginx.conf location /upload/ { mogilefs_tracker 172.16.45.3:7001; mogilefs_domain images; mogilefs_methods PUT DELETE; mogilefs_pass { proxy_pass $mogilefs_path; proxy_hide_header Content_Type; proxy_buffering off; } } [[email protected] nginx]# !ser
(2) 删除文件
[[email protected] nginx]# curl -X DELETE 172.16.45.3/upload/2.jpg
(3) 上传
[[email protected] ~]# curl -X PUT -T ‘/tmp/4.jpeg‘ 172.16.45.3/upload/4.jpeg