分布式檔案存儲系統Ceph
1 分布式檔案存儲系統Ceph
Ceph是一個統一的分布式存儲系統,設計初衷是提供較好的性能、可靠性和可擴充性。
對比說明 | TFS | FASTDFS | MooseFS | GlusterFS | CEPH |
開發語言 | C++ | C | C | C | C++ |
資料存儲方式 | 塊 | 檔案/Trunk | 塊 | 檔案/塊 | 對象/檔案/塊 |
線上擴容 | 支援 | 支援 | 支援 | 支援 | 支援 |
備援備份 | 支援 | 支援 | 支援 | 支援 | 支援 |
單點故障 | 存在 | 不存在 | 存在 | 不存在 | 不存在 |
易用性 | 安裝複雜,官方文檔少 | 安裝簡單,社群相對活躍 | 安裝簡單 | 官方文檔專業化 | 安裝有一定複雜度 |
适用場景 | 跨叢集的小檔案 | 單叢集的中小檔案 | 單叢集的大中檔案 | 跨叢集雲存儲 | 單叢集的大中小檔案 |
1.1 Ceph介紹
Ceph項目最早起源于Sage就讀博士期間的工作(最早的成果于2004年發表),并随後貢獻給開源社群。在經過了數年的發展之後,目前已得到衆多雲計算廠商的支援并被廣泛應用。RedHat及OpenStack都可與Ceph整合以支援虛拟機鏡像的後端存儲。
Ceph特點:
CRUSH算法:Crush算法是ceph的兩大創新之一,簡單來說,ceph摒棄了傳統的集中式存儲中繼資料尋址的方案,轉而使用CRUSH算法完成資料的尋址操作。CRUSH在一緻性哈希基礎上很好的考慮了容災域的隔離,能夠實作各類負載的副本放置規則,例如跨機房、機架感覺等。Crush算法有相當強大的擴充性,理論上支援數千個存儲節點。
高性能:Ceph中的資料副本數量可以由管理者自行定義,并可以通過CRUSH算法指定副本的實體存儲位置以分隔故障域,支援資料強一緻性; ceph可以忍受多種故障場景并自動嘗試并行修複。
高擴充性:Ceph本身并沒有主要節點,擴充起來比較容易,并且理論上,它的性能會随着磁盤數量的增加而線性增長。
特性豐富:Ceph支援三種調用接口:對象存儲,塊存儲,檔案系統挂載。三種方式可以一同使用。在國内一些公司的雲環境中,通常會采用ceph作為openstack的唯一後端存儲來提升資料轉發效率。
中文學習網:http://docs.ceph.org.cn/
Ceph架構:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CN4kzM1kTYmZDNiJDO3QmYyYzX1EzNxgTMwMzLcZDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
元件對象講解:
RADOS:就是這樣一個可用于PB級規模資料存儲叢集的可伸縮的、可靠的對象存儲服務,可以了解成Ceph的整個存儲對象,包括邏輯對象。
File:使用者上傳的檔案
object:上傳的檔案被切成N個小檔案塊對象,RADOS的基本存儲單元。
MDS:中繼資料的記憶體緩存,為了加快中繼資料的通路。
CRUSH:Ceph尋址算法,用于計算目前檔案存儲到哪個PG對應的OSD中。
PG:對object的存儲進行組織和位置映射。具體而言,一個PG負責組織若幹個object(可以為數千個甚至更多),但一個object隻能被映射到一個PG中,即,PG和object之間是“一對多”映射關系。同時,一個PG會被映射到n個OSD上,而每個OSD上都會承載大量的PG,即,PG和OSD之間是“多對多”映射關系。
OSD:RADOS中的存儲節點被稱為OSD
架構圖講解:
1:檔案上傳,先将檔案切片成N個object(如果開啟了cephFS,可以使用MDS緩存)
2:切片後的檔案object會存入到Ceph中
3:檔案存儲前,會經過CRUSH算法,計算目前檔案存儲歸結于哪個PG
4:PG是邏輯概念上對檔案存儲範圍劃分的索引
5:根據PG索引将檔案存儲到指定伺服器的OSD中
1.2 Ceph叢集搭建
叢集結構如上圖,server1作為主節點(Dashbaord、mon、mds、rgw、mgr、osd),server2和server3作為子節點(mon、mds、rgw、mgr、osd)。
節點中資訊說明:
dashbaord:Ceph可視化管理界面。
rgw:RADOSGW,Ceph對象網關,使用戶端能夠利用标準對象存儲API來通路Ceph叢集。
mgr:ceph-mgr,主要目标實作 ceph 叢集的管理,為外界提供統一的入口。
節點資訊:
server1:192.168.100.131
server2:192.168.100.132
server3:192.168.100.133
1.2.1 準備工作
1)機器名稱修改(131、132、133都執行)
我們給每台機器一個别名
192.168.100.131
->CENTOS1,
192.168.100.132
->CENTOS2,
192.168.100.133
->CENTOS3。
修改
192.168.100.131
/etc/hostname,添加CENTOS1
修改
192.168.100.(同上)
/etc/hostname,添加CENTOS2(同上)
修改
192.168.100.133
/etc/hostname,添加CENTOS3(同上)
配置名字解析IP:分别修改
131
、
132
、
133
的
/etc/hosts
檔案,添加如下映射:
192.168.100.131 CENTOS1
192.168.100.132 CENTOS2
192.168.100.133 CENTOS3
2)YUM源修改(131、132、133都執行)
這裡采用清華鏡像源,提升加載速度。
vi /etc/yum.repos.d/ceph.repo
,添加如下内容:
[Ceph]
name=Ceph packages for $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/ceph/rpm-mimic/el7/x86_64/
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://download.ceph.com/keys/release.asc
[Ceph-noarch]
name=Ceph noarch packages
# 清華源
baseurl=https://mirrors.tuna.tsinghua.edu.cn/ceph/rpm-mimic/el7/noarch/
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://download.ceph.com/keys/release.asc
[ceph-source]
name=Ceph source packages
baseurl=https://mirrors.tuna.tsinghua.edu.cn/ceph/rpm-mimic/el7/SRPMS/
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://download.ceph.com/keys/release.asc
3)ceph與ceph-deploy安裝(131)
更新yum源,并安裝
ceph
和
ceph-deploy
,這個過程非常耗時間,執行如下指令:
yum update && yum -y install ceph ceph-deploy
注意:
yum update
和
yum -y install python2-pip
最好在每台機器都更新下yum。
安裝過程中, 如果執行ceph-deploy出現
ImportError: No module named pkg_resources
,則需要安裝python2-pip,執行
yum -y install python2-pip
安裝即可。
如果遇到如下錯誤,安裝下epel即可。
操作指令:(最好先執行該指令)
yum install epel-release -y
yum install lttng-ust -y
4)NTP時間同步工具(131執行)
為了保證時間同步,我們需要安裝NTP時間同步工具:
yum install ntp ntpdate ntp-doc -y
設為開機啟動:
systemctl enable ntpd
設定每隔1小時自動校準同步。編輯
vi /etc/rc.d/rc.local
追加:
/usr/sbin/ntpdate ntp1.aliyun.com > /dev/null 2>&1; /sbin/hwclock -w
配置定時任務, 執行crontab -e 加入:
0 */1 * * * ntpdate ntp1.aliyun.com > /dev/null 2>&1; /sbin/hwclock -w
5)免密配置(131、132、133都執行)
官方建議不用系統内置使用者, 建立名為cuser使用者, 密碼也設為cuser:
useradd -d /home/cuser -m cuser
passwd cuser
設定sudo權限:(免密+隻讀權限)
echo "cuser ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cuser
sudo chmod 0440 /etc/sudoers.d/cuser
6)生成秘鑰:(131執行)
切換使用者: su cuser
執行ssh-keygen,一直按預設提示點選生成RSA密鑰資訊。
分發密鑰至各機器節點
ssh-copy-id cuser@CENTOS1
ssh-copy-id cuser@CENTOS2
ssh-copy-id cuser@CENTOS3
修改管理節點上的
~/.ssh/config
(目前使用者目錄下的.ssh/config)檔案, 簡化SSH遠端連接配接時的輸入資訊:
管理節點是會有root和cuser多個使用者, ssh遠端連接配接預設會以目前使用者身份進行登陸, 如果我們是root身份進行遠端連接配接, 還是需要輸入密碼,我們可以修改配置 使用root遠端連接配接時也不用輸入密碼。
切換root身份,
su root
編輯config
vi ~/.ssh/config
添加如下内容:
Host CENTOS1
Hostname CENTOS1
User cuser
Host CENTOS2
Hostname CENTOS2
User cuser
Host CENTOS3
Hostname CENTOS3
User cuser
修改檔案權限:
chmod 600 ~/.ssh/config
禁用SELINUX:
vi /etc/selinux/config
SELINUX=disabled
1.2.2 叢集搭建
安裝叢集,用root安裝,可以避免很多權限問題。
1)建立叢集管理目錄,作為ceph配置資訊存儲目錄。
mkdir -p /usr/local/bobo/cephcluster
cd /usr/local/bobo/cephcluster
2)建立叢集
ceph-deploy new CENTOS1 CENTOS2 CENTOS3
建立成功後, 會生配置檔案和秘鑰資訊。
3)修改配置檔案
編輯ceph.conf檔案
vi /usr/local/bobo/cephcluster/ceph.conf
,添加如下配置:
#對外開放網段
public network = 192.168.100.0/24
# 設定pool池預設配置設定數量
osd pool default size = 2
# 容忍更多的時鐘誤差
mon clock drift allowed = 2
mon clock drift warn backoff = 30
# 允許删除pool
mon_allow_pool_delete = true
[mgr]
# 開啟WEB儀表盤
mgr modules = dashboard
注意:Pool是存儲對象的邏輯分區,它規定了資料備援的類型和對應的副本分布政策。
完整内容如下:
檔案修改後執行安裝(131執行),此時3台機器都會執行安裝執行如下安裝指令:
ceph-deploy install CENTOS1 CENTOS2 CENTOS3
如果出現
ceph_deploy][ERROR ] RuntimeError: Failed to execute command: ceph --version
錯誤,可以直接在每個節點單獨執行
yum -y install ceph
進行單獨安裝。如果沒有倉庫檔案ceph.repo, 按上面的步驟手工建立。
4)初始化Monitor資訊
ceph-deploy mon create-initial
此時會生成很多秘鑰檔案資訊
5)同步管理資訊
ceph-deploy admin CENTOS1 CENTOS2 CENTOS3
6)安裝mgr(管理守護程序)
ceph-deploy mgr create CENTOS1 CENTOS2 CENTOS3
7)安裝rgw
ceph-deploy rgw create CENTOS1 CENTOS2 CENTOS3
mds服務:
ceph-deploy mds create CENTOS1 CENTOS2 CENTOS3
注意:任意一個環節安裝失敗了,需要解除安裝重裝:
ceph-deploy purge CENTOS1 CENTOS2 CENTOS3
ceph-deploy purgedata CENTOS1 CENTOS2 CENTOS3
ceph-deploy forgetkeys
将三台節點的mon資訊也删除:
rm -rf /var/run/ceph/
如果出現錯誤:
ceph_deploy][ERROR ] RuntimeError: Failed to execute command: ceph --version
可以在各節點上單獨進行安裝:
yum -y install ceph
8)OSD安裝
OSD服務是對象存儲守護程序, 負責把對象存儲到本地檔案系統, 必須要有一塊獨立的磁盤作為存儲。如果沒有獨立磁盤,怎麼辦? 可以在Linux下面建立一個虛拟磁盤進行挂載。
添加磁盤:
執行
fdisk -l
檢視磁盤資訊如下,我們需要添加一個磁盤,直接用
VMware
添加即可。
使用
VMware
選擇設定->硬碟->添加,如下圖:
一直點選下一步,設定磁盤空間大小為10G即可。操作完後重新開機虛拟機,并輸入
fdisk -l
檢視磁盤資訊如下,明顯多了
/dev/sdb
10G大小。
執行建立OSD指令:(注意,每條指令都是在131中執行,不要在每台機器中單獨執行)
ceph-deploy osd create --data /dev/sdb CENTOS1
ceph-deploy osd create --data /dev/sdb CENTOS2
ceph-deploy osd create --data /dev/sdb CENTOS3
Monitor檢視
在
/usr/bin
下執行
./ceph -s
可以檢視叢集狀态。
可以執行
ntpdate ntp1.aliyun.com
同步各個節點的時間。
如果出現如下情況,執行
systemctl restart ceph.target
重新開機每個節點即可(131,132,133都執行)。
1.2.3 dashboard安裝
Ceph 提供了原生的Dashboard功能,通過Dashboard可以擷取Ceph叢集的各種基本狀态資訊。我們接下來安裝一下Dashboard,并使用它的功能。
1)開啟dashboard子產品
ceph mgr module enable dashboard
2)生成簽名
ceph dashboard create-self-signed-cert
3)建立目錄
mkdir -p /usr/local/bobo/cephcluster/mgr-dashboard
4)生成密鑰對
openssl req -new -nodes -x509 -subj "/O=IT/CN=ceph-mgr-dashboard" -days 3650 -keyout dashboard.key -out dashboard.crt -extensions v3_ca
5)啟動dashboard
ceph mgr module disable dashboard
ceph mgr module enable dashboard
6)設定IP與PORT
ceph config set mgr mgr/dashboard/server_addr 192.168.100.131
ceph config set mgr mgr/dashboard/server_port 9001
7)關閉HTTPS
ceph config set mgr mgr/dashboard/ssl false
8)檢視服務資訊
ceph mgr services
9)設定管理者賬号密碼
ceph dashboard set-login-credentials admin admin
10)通路
<https://192.168.100.131:8443/#/dashboard>
11)RGW通路
通路 http://192.168.100.131:7480/ 效果如下:
1.3 Cephfs管理
叢集建立完後, 預設沒有檔案系統, 我們建立一個Cephfs可以支援對外通路的檔案系統。
1)建立兩個存儲池, 執行兩條指令:
ceph osd pool create cephfs_data 128
ceph osd pool create cephfs_metadata 64
少于5個OSD可把pg_num設定為128
OSD數量在5到10,可以設定pg_num為512
OSD數量在10到50,可以設定pg_num為4096
OSD數量大于50,需要計算pg_num的值
通過下面指令可以列出目前建立的存儲池:
ceph osd lspools
2)建立fs, 名稱為fs_test:
ceph fs new fs_test cephfs_metadata cephfs_data
3)狀态檢視, 以下資訊代表正常
ceph fs ls
:
name: fs_test, metadata pool: cephfs_metadata, data pools: [cephfs_data ]
ceph mds stat
:
fs_test-0/0/1 up
4)fuse挂載
先确定ceph-fuse指令能執行, 如果沒有, 則安裝:
yum -y install ceph-fuse
建立挂載目錄
mkdir -p /usr/local/gupao/cephfs_directory
挂載cephfs
ceph-fuse -k /etc/ceph/ceph.client.admin.keyring -m 192.168.100.131:6789 /usr/local/gupao/cephfs_directory
出現下面資訊表示挂載成功了:
ceph-fuse[28003]: starting fuse
5)挂載資訊檢視
[root@CENTOS1 cephcluster]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.1G 0 4.1G 0% /dev
tmpfs 4.1G 0 4.1G 0% /dev/shm
tmpfs 4.1G 20M 4.1G 1% /run
tmpfs 4.1G 0 4.1G 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 2.0G 16G 12% /
/dev/sda1 1014M 189M 826M 19% /boot
tmpfs 4.1G 28K 4.1G 1% /var/lib/ceph/osd/ceph-0
tmpfs 838M 0 838M 0% /run/user/0
ceph-fuse 13G 0 13G 0% /usr/local/gupao/cephfs_directory
1.4 Ceph Swift API接口開發
Swift是由Rackspace開發的用來為雲計算提供可擴充存儲的項目。專注于對象存儲, 并提供一套REST風格的Api來通路, 與Ceph強一緻性不同, 它是最終一緻性。兩者都是優秀的開源項目, 并無明顯優劣之分,在使用場景上有所不同, 如果是專注于對象存儲, 那麼可以選擇swift即可滿足需要, 如果還有塊存儲要求, 那麼選擇Ceph更為合适。這裡選擇Ceph, 因為通過網關可以适配相容swift api, 同時在資料通路上具有較強的擴充性。
1.4.1 準備工作
建立Swift使用者, 用于接口請求認證
sudo radosgw-admin user create --subuser="cephtester:subtester" --uid="cephtester" --display-name="cephtester" --key-type=swift --secret="gupao" --access=full
uid 為主使用者, subuser為子使用者資訊, secret指定密鑰, 不指定則随機生成, access擁有權限設定,代碼中需使用傳回資訊中的user和secret_key。
swift_keys:
"swift_keys": [
{
"user": "cephtester:subtester",
"secret_key": "gupao"
}
],
建立管理者賬号:
radosgw-admin user create --uid=mgruser --display-name=mgruser --system
傳回資訊如下:
{
"user_id": "mgruser",
"display_name": "mgruser",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"auid": 0,
"subusers": [],
"keys": [
{
"user": "mgruser",
"access_key": "AZ6L40PH9WB37EKVVMCZ",
"secret_key": "rk8PEjtYaMTo7nMDM62hqqN1tOnZPBEe4GA0LQMW"
}
],
"swift_keys": [],
"caps": [],
"op_mask": "read, write, delete",
"system": "true",
"default_placement": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw",
"mfa_ids": []
}
根據生成的access_key與secret_key, 執行:
ceph dashboard set-rgw-api-access-key AZ6L40PH9WB37EKVVMCZ
ceph dashboard set-rgw-api-secret-key rk8PEjtYaMTo7nMDM62hqqN1tOnZPBEe4GA0LQMW
打開管理界面,http://192.168.100.131:9001/#/rgw/user 可以檢視到我們剛才建立的兩個使用者:
1.4.2 檔案服務搭建
我們搭建一個單獨的工程,專門用于實作檔案上傳和檔案下載下傳,工程坐标如下:
<groupId>com.bobo.vip.mall</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>mall-file-service</artifactId>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mall-service</artifactId>
<groupId>com.gupaoedu.vip.mall</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mall-file-service</artifactId>
<description>
檔案上傳微服務
</description>
<dependencies>
<!-- Rados Java Api依賴 -->
<dependency>
<groupId>com.ceph</groupId>
<artifactId>rados</artifactId>
<version>0.6.0</version>
</dependency>
<!-- Cephfs 檔案系統依賴 -->
<dependency>
<groupId>com.ceph</groupId>
<artifactId>libcephfs</artifactId>
<version>0.80.5</version>
</dependency>
<!--swift-->
<dependency>
<groupId>org.javaswift</groupId>
<artifactId>joss</artifactId>
<version>0.10.2</version>
</dependency>
</dependencies>
</project>
bootstrap.yml:
server:
port: 8082
spring:
application:
name: mall-file
cloud:
nacos:
config:
file-extension: yaml
server-addr: 192.168.100.130:8848
discovery:
#Nacos的注冊位址
server-addr: 192.168.100.130:8848
ceph:
username: cephtester:subtester #Ceph配置 主使用者名:子使用者名
password: gupao #秘鑰
authUrl: http://192.168.100.131:7480/auth/1.0 #接口通路路徑
defaultContainerName: user_datainfo #預設容器名字
#圖檔路徑
cephurl: http://localhost:8082/file/download/
#日志配置
logging:
pattern:
console: "%msg%n"
建立
com.bobo.vip.mall.file.ceph.ContainerConfig
配置類,在類中建立
Account
和
Container
對象,代碼如下:
@Configuration
@ConfigurationProperties(prefix = "ceph")
@Data
public class ContainerConfig {
private String username;
private String password;
private String authUrl;
private String defaultContainerName;
/***
* Ceph的賬戶資訊配置
* @return
*/
@Bean
public Account account(){
// Ceph的賬戶資訊配置
AccountConfig config = new AccountConfig();
config.setUsername(username);
config.setPassword(password);
config.setAuthUrl(authUrl);
config.setAuthenticationMethod(AuthenticationMethod.BASIC);
return new AccountFactory(config).createAccount();
}
/***
* 容器對象
* @return
*/
@Bean
public Container container(){
// 擷取容器資訊
Container newContainer = account().getContainer(defaultContainerName);
if(!newContainer.exists()) {
return newContainer.create();
}else {
return newContainer;
}
}
}
建立檔案上傳下載下傳工具類
com.gupaoedu.vip.mall.file.ceph.FileHandler
,代碼如下:
@Component
public class FileHandler {
@Autowired
private Container container;
/****
* 檔案上傳
*/
public void upload(String filename,byte[] buffer) {
//擷取容器對象
StoredObject object = container.getObject(filename);
//檔案上傳
object.uploadObject(buffer);
}
/***
* 檔案下載下傳
*/
public byte[] download(String filename){
//擷取容器中遠端存儲的資訊
StoredObject object = container.getObject(filename);
//執行檔案下載下傳
byte[] bytes = object.downloadObject();
return bytes;
}
}
控制器建立:
com.gupaoedu.vip.mall.file.controller.FileController
@RestController
@RequestMapping(value = "/file")
public class FileController {
@Autowired
private FileHandler fileHandler;
@Value("${cephurl}")
private String cephurl;
/***
* 檔案上傳
* @param file
* @return
*/
@PostMapping(value = "/upload")
public RespResult upload(MultipartFile file) throws IOException {
//上傳
fileHandler.upload(file.getOriginalFilename(),file.getBytes());
return RespResult.ok(cephurl+file.getOriginalFilename());
}
/***
* 下載下傳
* @return
*/
@GetMapping(value = "/download/{filename}")
public void download(@PathVariable String filename, HttpServletResponse response) throws IOException {
//下載下傳
byte[] bytes = fileHandler.download(filename);
//輸出檔案
ServletOutputStream os = response.getOutputStream();
os.write(bytes);
}
}
建立啟動類:
com.gupaoedu.vip.mall.file.MallFileApplication
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class MallFileApplication {
public static void main(String[] args) {
SpringApplication.run(MallFileApplication.class,args);
}
}
檔案上傳測試http://localhost:8082/file/upload
檔案下載下傳測試