#######################################################################
資料存儲的趨勢和大資料帶來的挑戰
分布式存儲與CAP定理
分布式存儲檔案系統
Mogilefs基本原理
Mogilefs實作
Nginx反向代理Tracker節點
當下我們處在一個網際網路飛速發展的資訊社會,在海量并發連接配接的驅動下每天所産生的資料量必然以幾何方式增長,随着資訊連接配接方式日益多樣化,資料存儲的結構也随着發生了變化。在這樣的壓力下使得人們不得不重新審視大量資料的存儲所帶來的挑戰,例如:資料采集、資料存儲、資料搜尋、資料共享、資料傳輸、資料分析、資料可視化等一系列問題。
傳統存儲在面對海量資料存儲表現出的力不從心已經是不争的事實,例如:縱向擴充受陣列空間限制、橫向擴充受交換裝置限制、節點受檔案系統限制。
然而分布式存儲的出現在一定程度上有效的緩解了這一問題,之是以稱之為緩解是因為分布式存儲在面對海量資料存儲時也并非十全十美毫無壓力,依然存在的難點與挑戰例如:節點間通信、資料存儲、資料空間平衡、容錯、檔案系統支援等一系列問題仍處在不斷摸索和完善中。
首先要說明的是一個完美分布式系統有三個最重要的元素,他們分别是:
一緻性(Consistency):任何一個讀操作總是能讀取之前完成的寫操作。
可用性(Availability):每次操作總是能夠在預定時間傳回。
分區容錯性(Partition Tolerance):在出現網絡分區(分布式)的情況下,仍然能夠滿足一緻性和可用性。
<a target="_blank" href="http://blog.51cto.com/attachment/201312/032623364.png"></a>
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 ----> 弱一緻性
Google Filesystem
GFS+MapReduce擅長處理單個大檔案
Hadoop Distributed Filesystem
GFS的山寨版+MapReduce,擅長處理單個大檔案
ClusterFS
擅長處理單個大檔案
Taobao Filesystem
擅長處理海量小檔案
MogileFS
Ceph
是一個 Linux PB級别的分布式檔案系統
MooseFS
通用簡便,适用于研發能力不強的公司
Lustre
一種平行分布式檔案系統
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:複制最小機關,檔案屬性管理,定義檔案存儲在不同裝置上份數。
流程圖如下:
1、應用層發起GET請求到Nginx。
2、Nginx根據負載均衡機制随機代理到背景Node one。
3、Node one向從伺服器發起查詢請求。
4、從伺服器傳回查詢結果。
5、Node one将查詢結果傳回給Nginx。
6、Nginx将查詢結果根據子產品轉換為合理的url方位Node three。
7、Node Three将檔案内容通過http協定傳回給Nginx。
8、Nginx将結果傳回給應用層的請求。
由于各角色和服務之間都是基于套接字通信,就服務本身來說沒有耦合性,是以可以使用少量機器運作多種服務角色,功能圖如下:
<a target="_blank" href="http://blog.51cto.com/attachment/201312/034037457.png"></a>
1、通過Nginx+Keepalived實作高可用的負載均衡,通過upstream子產品可以有選擇性的轉發應用層的請求至後端tracker節點。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<code>##### Database節點</code>
<code>安裝mariadb</code>
<code>授權</code>
<code>GRANT ALL ON *.* TO </code><code>'root'</code><code>@</code><code>'%'</code> <code>IDENTIFIED BY </code><code>'mypass'</code><code>;</code>
<code>CREATE DATABASE mogilefs;</code>
<code>GRANT ALL ON mogilefs.* TO </code><code>'moguser'</code><code>@</code><code>'%'</code> <code>IDENTIFIED BY </code><code>'mogpass'</code><code>;</code>
<code>FLUSH PRIVILEGES;</code>
<code>##### Tracker節點(可以是所有節點)</code>
<code>安裝 mogilefs</code>
<code>修改配置檔案如下</code>
<code>vim </code><code>/etc/mogilefs/mogilefsd</code><code>.conf </code>
<code>daemonize = 1</code>
<code>pidfile = </code><code>/var/run/mogilefsd/mogilefsd</code><code>.pid</code>
<code>db_dsn = DBI:mysql:mogilefs:host=192.168.1.241</code>
<code>db_user = moguser</code>
<code>db_pass = mogpass</code>
<code>listen = 0.0.0.0:7001</code>
<code>conf_port = 7001</code>
<code>query_jobs = 100</code>
<code>delete_jobs = 1</code>
<code>replicate_jobs = 5</code>
<code>reaper_jobs = 1</code>
<code>service mogilefsd start </code><code>#啟動服務</code>
<code>ss -tanlp (LISTEN 0 128 192.168.1.241:7001 )</code>
<code>##### storage節點(可以是所有節點)</code>
<code>mkdir</code> <code>/mogdata/dev1</code> <code>-pv </code><code>#建立裝置目錄</code>
<code>chown</code> <code>-R mogilefs.mogilefs </code><code>/mogdata/dev2/</code> <code>#權限</code>
<code>vim </code><code>/etc/mogilefs/mogstored</code><code>.conf</code>
<code>maxconns = 10000</code>
<code>httplisten = 0.0.0.0:7500</code>
<code>mgmtlisten = 0.0.0.0:7501</code>
<code>docroot = </code><code>/mogdata</code> <code>#目錄級别</code>
<code>service mogstored start</code>
<code>ss -tanlp (*:7500)</code>
<code>##### tracker節點添加storage節點和常用指令</code>
<code>mogadm check </code><code>#檢測節點</code>
<code>mogadm host list </code><code>#每個存儲節點稱為一個host</code>
<code>mogadm host add 192.168.1.213 --ip=192.168.1.213 --ip=192.168.1.213 --status=alive </code><code>#添加第一個存儲節點</code>
<code>mogadm host add 192.168.1.242 --ip=192.168.1.242 --ip=192.168.1.242 --status=alive </code><code>#添加第一個存儲節點</code>
<code>mogadm host add 192.168.1.241 --ip=192.168.1.241 --ip=192.168.1.241 --status=alive </code><code>#添加第一個存儲節點</code>
<code>mogadm device add 192.168.1.213 1 </code><code>#添加第一個裝置,裝置号唯一不能重名</code>
<code>mogadm device add 192.168.1.242 2 </code><code>#添加第二個裝置</code>
<code>mogadm device add 192.168.1.241 3 </code><code>#添加第三個裝置</code>
<code>mogadm check </code><code>#可以檢視狀态</code>
<code>mogadm domain add files </code><code>#建立檔案存儲域</code>
<code>mogadm domain add images </code><code>#建立圖檔存儲域</code>
<code>mogadm domain list </code><code>#檢視所有域</code>
<code>mogupload --trackers=192.168.1.241 --domain=files --key=</code><code>'/fstab'</code> <code>--</code><code>file</code><code>=</code><code>'/etc/fstab'</code> <code>#上傳fstab檔案,key為'/fstab'</code>
<code>mogfileinfo --trackers=192.168.1.241 --domain=files --key=</code><code>'/fstab'</code> <code>#根據key檢視檔案存放資訊</code>
注釋:mogupload工具是為了測試,實際環境中上傳是由程式員在代碼中使用mogilefs的API進行互動。
<a target="_blank" href="http://blog.51cto.com/attachment/201312/042651555.png"></a>
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<code>##### 配置Nginx</code>
<code>安裝tng</code>
<code>yum </code><code>install</code> <code>pcre-devel -y</code>
<code>yum groupinstall </code><code>"Development Tools"</code> <code>"Server Platform Development"</code>
<code>yum </code><code>install</code> <code>libxslt-devel gd-devel lua-devel geoip-devel</code>
<code>tengine-1.5.1.</code><code>tar</code><code>.gz</code>
<code>nginx-mogilefs-module-master.zip </code><code>#mogilefs子產品需要打更新檔</code>
<code>mkdir</code> <code>-pv </code><code>/var/tmp/nginx/client</code> <code>#子產品需要</code>
<code>unzip nginx-mogilefs-module-master.zip</code>
<code>useradd</code> <code>-r nginx</code>
<code>.</code><code>/configure</code> <code>\</code>
<code> </code><code>--prefix=</code><code>/usr/local/nginx</code> <code>\</code>
<code> </code><code>--sbin-path=</code><code>/usr/local/nginx/sbin/nginx</code> <code>\</code>
<code> </code><code>--conf-path=</code><code>/etc/nginx/nginx</code><code>.conf \</code>
<code> </code><code>--error-log-path=</code><code>/var/log/nginx/error</code><code>.log \</code>
<code> </code><code>--http-log-path=</code><code>/var/log/nginx/access</code><code>.log \</code>
<code> </code><code>--pid-path=</code><code>/var/run/nginx/nginx</code><code>.pid \</code>
<code> </code><code>--lock-path=</code><code>/var/lock/nginx</code><code>.lock \</code>
<code> </code><code>--user=nginx \</code>
<code> </code><code>--group=nginx \</code>
<code> </code><code>--</code><code>enable</code><code>-mods-shared=all \</code>
<code> </code><code>--add-module=</code><code>/nginx-mogilefs-module-master</code>
<code>make</code> <code>&& </code><code>make</code> <code>install</code>
<code>vim </code><code>/etc/profile</code><code>.d</code><code>/nginx</code><code>.sh</code>
<code>export</code> <code>PATH=</code><code>/usr/local/nginx/sbin</code><code>:$PATH</code>
<code>. !$</code>
<code>提供腳本.....</code>
<code>配置nginx</code>
<code>vim </code><code>/etc/nginx/nginx</code><code>.cfg</code>
<code>upstream trackers {</code>
<code> </code><code>server 192.168.1.242:7001 weight=1;</code>
<code> </code><code>server 192.168.1.213:7001 weight=1;</code>
<code> </code><code>server 192.168.1.241:7001 backup;</code>
<code> </code><code>check interval=3000 rise=2 fall=5 timeout=1000;</code>
<code> </code><code>check_http_send </code><code>"GET / HTTP/1.0\r\n\r\n"</code><code>;</code>
<code> </code><code>check_http_expect_alive http_2xx http_3xx;</code>
<code> </code><code>}</code>
<code>location </code><code>/jpg/</code> <code>{</code>
<code> </code><code>mogilefs_tracker trackers;</code>
<code> </code><code>mogilefs_domain images;</code>
<code> </code><code>mogilefs_methods GET;</code>
<code> </code><code>mogilefs_pass {</code>
<code> </code><code>proxy_pass $mogilefs_path;</code>
<code> </code><code>proxy_hide_header Content-Type;</code>
<code> </code><code>proxy_buffering off;</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code>##### 配置keepalived</code>
<code>安裝keepalived</code>
<code>vim </code><code>/etc/keepalived/keepalived</code><code>.conf </code><code># backup priority 99</code>
<code>global_defs {</code>
<code> </code><code>notification_email {</code>
<code> </code><code>root@localhost</code>
<code> </code><code>notification_email_from admin@localhost</code>
<code> </code><code>smtp_server 127.0.0.1</code>
<code> </code><code>smtp_connect_timeout 30</code>
<code> </code><code>router_id LTT</code>
<code>}</code>
<code>vrrp_script chk_nginx {</code>
<code> </code><code>script </code><code>"killall -0 nginx"</code>
<code> </code><code>interval 1</code>
<code> </code><code>weight -2</code>
<code> </code><code>fall 2</code>
<code> </code><code>rise 1</code>
<code>vrrp_instance IN_1 {</code>
<code> </code><code>state MASTER</code>
<code> </code><code>interface eth0</code>
<code> </code><code>virtual_router_id 22</code>
<code> </code><code>priority 100</code>
<code> </code><code>advert_int 1</code>
<code> </code><code>authentication {</code>
<code> </code><code>auth_type PASS</code>
<code> </code><code>auth_pass aaaa</code>
<code> </code><code>}</code>
<code> </code><code>virtual_ipaddress {</code>
<code> </code><code>192.168.1.222</code>
<code> </code><code>track_script {</code>
<code> </code><code>chk_nginx</code>
檢視負載節點:
<a target="_blank" href="http://blog.51cto.com/attachment/201312/045554770.png"></a>
模拟GET方法測試Nginx_mogilefs子產品:
<a target="_blank" href="http://blog.51cto.com/attachment/201312/045933806.png"></a>
本文轉自 ftmoonfans 51CTO部落格,原文連結:http://blog.51cto.com/soulboy/1338192