天天看點

分布式存儲Ceph(二) Ceph基礎

二 Ceph基礎

2.1 Ceph 簡介

  • ceph 是一個開源的分布式存儲系統, 同時支援檔案存儲(cephfs)、塊存儲(rbd)和對象存儲(rgw)的分布式存儲系統,具有高擴充性、高性能、高可靠性等優點。
  • ceph 是一個對象(object)式存儲系統, 它把每一個待管理的資料流(檔案等資料)切分為一到多個固定大小(預設 4 兆)的對象資料, 并以其為原子單元(原子是構成元素的最小單元)完成資料的讀寫。

2.2 Ceph特點

  • 高性能
  • 摒棄了傳統的集中式存儲中繼資料尋址的方案,采用CRUSH算法,資料分布均衡,并行度高。
  • 考慮了容災域的隔離,能夠實作各類負載的副本放置規則,例如跨機房、機架等。
  • 能夠支援上千個存儲節點的規模,支援TB到PB級的資料。
  • 高可用性
  • 副本數可以靈活控制。
  • 支援故障域分割,資料強一緻性。
  • 多重故障場景自動進行修複自愈。
  • 沒有單點故障,自動管理。
  • 高可擴充性
  • 去中心化。
  • 擴充靈活。
  • 随着節點增加而線性增長。
  • 特性豐富
  • 支援三種存儲接口:塊存儲、檔案存儲、對象存儲。
  • 支援自定義接口,支援多種語言驅動。

2.3 Ceph存儲架構

  • Ceph支援三種接口:
  • Object:有原生的API,而且也相容Swift和S3的API,适合單用戶端使用。
  • Block:支援精簡配置、快照、克隆,适合多用戶端有目錄結構。
  • File:Posix接口,支援快照。
分布式存儲Ceph(二) Ceph基礎

2.4 Ceph邏輯組織架構

  • Pool:存儲池、分區,存儲池的大小取決于底層的存儲空間。
  • PG(placement group):一個pool内部可以有多個PG存在,pool和PG都是抽象的邏輯概念,一個pool中有多少個PG可以通過公式計算。
  • OSD(Object Storage Daemon):每一塊磁盤都是一個osd,一個主機由一個或多個osd組成。

ceph叢集部署好之後,要先建立存儲池才能向ceph寫入資料,檔案在想ceph儲存之前要先進行一緻性hash計算,計算後會把檔案儲存在某個對象的PG,此檔案一定屬于某個pool的一個PG,在通過PG儲存在OSD上。

資料對象在寫到主OSD之後在同步從OSD以實作資料的高可用。

分布式存儲Ceph(二) Ceph基礎

2.4.1 Ceph檔案存儲過程

  1. 一個檔案将會切割為多個object(如1G檔案每個object為4M将切割為256個),每個object會由一個由innode(ino)和object編号(ono)組成oid,即object id,oid是真個叢集唯一,唯一辨別object對象;
  2. 針對object id做hash并做取模運算,進而擷取到pgid,即place group id,通過hash+mask擷取到PGs ID,PG是存儲object的容器;
  3. Ceph通過CRUSH算法,将pgid進行運算,找到目前叢集最适合存儲PG的OSD節點,如osd1和osd2(假設為2個副本);
  4. PG的資料最終寫入到OSD節點,完成資料的寫入過程,當然這裡會涉及到多副本,一份資料寫多副本;
  5. 主OSD将資料同步給備份OSD,并等待備份OSD傳回确認;
  6. 主OSD将寫入完成傳回給用戶端。

2.5 Ceph存儲類型

  • ​​https://docs.ceph.com/en/pacific/rbd/​​

2.5.1 塊存儲(RBD)

2.5.1.1 塊存儲介紹

  • 一個塊是一個位元組序列(通常為 512)。基于塊的存儲接口是将資料存儲在包括 HDD、SSD、CD、軟碟甚至錄音帶在内的媒體上的一種成熟且常見的方式。無處不在的塊裝置接口非常适合與包括 Ceph 在内的海量資料存儲進行互動。
  • 塊存儲(RBD)需要格式化,将檔案直接儲存到磁盤上。

2.5.1.2 塊存儲結構圖

  • Ceph 塊裝置是精簡配置的、可調整大小的,并存儲在多個 OSD 上條帶化的資料。Ceph 塊裝置利用 RADOS功能,包括快照、複制和強一緻性。Ceph 塊存儲用戶端通過核心子產品或​

    ​librbd​

    ​庫與 Ceph 叢集通信。

2.5.1.3 塊存儲特性

  1. Thin-provisioned 瘦配置設定,即先配置設定特定存儲大小,随着使用實際使用空間的增長而占用存儲空間,避免空間占用;
  2. Images up to 16 exabytes 耽擱景象最大能支援16EB;
  3. Configurable striping 可配置的切片,預設是4M;
  4. In-memory caching 記憶體緩存;
  5. Snapshots 支援快照,将當時某個狀态記錄下載下傳;
  6. Copy-on-write cloning Copy-on-write克隆複制功能,即制作某個鏡像實作快速克隆,子鏡像依賴于母鏡像;
  7. Kernel driver support 核心驅動支援,即rbd核心子產品;
  8. KVM/libvirt support 支援KVM/libvirt,實作與雲平台如openstack,cloudstack內建的基礎;
  9. Back-end for cloud solutions 雲計算多後端解決方案,即為openstack,kubernetes提供後端存儲;
  10. Incremental backup 增量備份;
  11. Disaster recovery (multisite asynchronous replication) 災難恢複,通過多站點異步複制,實作資料鏡像拷貝。

2.5.1.4 塊存儲優點

  1. 通過RAID與LVM等手段,對資料提供保護。
  2. 多塊廉價的硬碟組合起來,提供容量。
  3. 多塊磁盤組合出來的邏輯盤,提高讀寫效率。

2.5.1.5 塊存儲缺點

  1. 采用SAN架構組網時,光纖交換機,造價成本高。
  2. 主機之間無法共享資料。

2.5.1.6 塊存儲使用場景

  1. docker容器、虛拟機磁盤。
  2. 日志存儲。
  3. 檔案存儲。

2.5.2 CephFS

  • ​​https://docs.ceph.com/en/pacific/cephfs/​​

2.5.2.1 CephFS介紹

  • Ceph 檔案系統或CephFS是一個符合 POSIX 的檔案系統,它建構在 Ceph 的分布式對象存儲RADOS之上。CephFS 緻力于為各種應用程式提供最先進的、多用途、高可用性和高性能的檔案存儲,包括共享主目錄、HPC 暫存空間和分布式工作流共享存儲等傳統用例。
  • CephFS 通過使用一些新穎的架構選擇來實作這些目标。值得注意的是,檔案中繼資料與檔案資料存儲在一個單獨的 RADOS 池中,并通過可調整大小的中繼資料伺服器叢集或MDS 提供服務,該叢集可以擴充以支援更高吞吐量的中繼資料工作負載。檔案系統的用戶端可以直接通路 RADOS 來讀取和寫入檔案資料塊。出于這個原因,工作負載可能會随着底層 RADOS 對象存儲的大小線性擴充;也就是說,沒有網關或代理為用戶端調解資料 I/O。
  • CephFS提供資料存儲的接口,是由作業系統針對塊存儲的應用,即由作業系統提供存儲接口,應用程式通過調用作業系統将檔案儲存到塊存儲進行持久化。
  • 要使用CephFS,需要部署cephfs服務。
  • 從 Pacific 版本開始,支援多檔案系統穩定且可以使用。此功能允許在單獨的池上配置具有完全資料分離的單獨檔案系統。

2.5.2.2 CephFS架構圖

  • 對資料的通路通過 MDS 叢集進行協調,MDS 叢集作為用戶端和 MDS 共同維護的分布式中繼資料緩存狀态的權限。中繼資料的變異被每個 MDS 聚合成一系列有效的寫入到 RADOS 上的日志;MDS 不會在本地存儲中繼資料狀态。此模型允許在 POSIX 檔案系統上下文中的用戶端之間進行連貫且快速的協作。

2.5.2.3 CephFS特性

  1. POSIX-compliant semantics POSIX風格接口;
  2. Separates metadata from data 中繼資料metadata和資料data分開存儲;
  3. Dynamic rebalancing 動态資料均衡;
  4. Subdirectory snapshots 子目錄快照;
  5. Configurable striping 可配置切割大小;
  6. Kernel driver support 核心驅動支援,即CephFS;
  7. FUSE support 支援FUSE風格;
  8. NFS/CIFS deployable 支援NFS/CIFS形式部署;
  9. Use with Hadoop (replace HDFS) 可支援與Hadoop繼承,替換HDFS存儲。

2.5.2.4 CephFS優點

  1. 造價低,随便一台機器就可以。
  2. 友善檔案共享。

2.5.2.5 CephFS缺點

  1. 讀寫效率低。
  2. 傳輸速率慢。

2.5.2.6 CephFS使用場景

  1. 日志存儲。
  2. FTP、NFS。
  3. 有目錄結構的檔案存儲。

2.5.3 對象存儲(Object)

  • ​​https://docs.ceph.com/en/pacific/radosgw/​​

2.5.3.1 對象存儲介紹

  • 對象存儲(Object)也稱為基于對象的存儲,其中的檔案被拆分成多個部分并散布在多個存儲伺服器,在對象存儲中,資料會被分解稱為“對象”的離散單元,并儲存在單個存儲庫中,而不是作為檔案夾中的檔案或伺服器上的塊來儲存,對象存儲需要一個簡單的HTTP應用程式設計接口(API),以供大多數用戶端使用。
  • Ceph 對象存儲支援兩個接口。
  1. S3 相容:通過與 Amazon S3 RESTful API 的大部分子集相容的接口提供對象存儲功能。
  2. Swift 相容:通過與 OpenStack Swift API 的大部分子集相容的接口提供對象存儲功能。

2.5.3.2 對象存儲架構圖

  • Ceph 對象存儲使用 Ceph 對象網關守護程序 (​

    ​radosgw​

    ​),它是一個 HTTP 伺服器,用于與 Ceph 存儲叢集互動。由于它提供了與 OpenStack Swift 和 Amazon S3 相容的接口,是以 Ceph 對象網關有自己的使用者管理。Ceph 對象網關可以将資料存儲在用于存儲來自 Ceph 檔案系統用戶端或 Ceph 塊裝置用戶端的資料的同一個 Ceph 存儲叢集中。S3 和 Swift API 共享一個公共命名空間,是以您可以使用一個 API 編寫資料并使用另一個 API 檢索資料。

2.5.3.3 對象存儲特性

  1. RESTful Interface RESTful風格接口;
  2. S3- and Swift-compliant APIs 提供相容于S3和Swfit風格API;
  3. S3-style subdomains S3風格的目錄風格;
  4. Unified S3/Swift namespace 統一扁平的S3/Swift命名空間,即所有的對象存放在同一個平面上;
  5. User management 提供使用者管理認證接入;
  6. Usage tracking 使用情況追蹤;
  7. Striped objects 對象切割,将一個大檔案切割為多個小檔案(objects);
  8. Cloud solution integration 雲計算解決方案即成,可以與Swfit對象存儲即成;
  9. Multi-site deployment 多站點部署,保障可靠性;
  10. Multi-site replication 多站點複制,提供容災方案。

2.5.3.4 對象存儲 優點

  1. 具備塊存儲的讀寫高速。
  2. 具備檔案存儲的共享等特性。

2.5.3.5 對象存儲使用場景

  1. 圖檔存儲。
  2. 視訊存儲。

2.6 Ceph 概念介紹

2.6.1 RADOS

  • 全稱Reliable Autonomic Distributed Object Store,即可靠的、自動化的、分布式對象存儲系統。RADOS是Ceph叢集的精華,使用者實作資料配置設定、Failover等叢集操作。

2.6.2 Librados

  • Rados提供庫,因為RADOS是協定很難直接通路,是以上層的RBD、RGW和CephFS都是通過librados通路的,目前提供PHP、Ruby、Java、Python、C和C++支援。

2.6.3 Crush

  • Crush算法是Ceph的兩大創新之一,通過Crush算法的尋址操作,Ceph得以摒棄了傳統的集中式存儲中繼資料尋址方案。而Crush算法在一緻性哈希基礎上很好的考慮了容災域的隔離,使得Ceph能夠實作各類負載的副本放置規則,例如跨機房、機架感覺等。同時,Crush算法有相當強大的擴充性,理論上可以支援數千個存儲節點,這為Ceph在大規模雲環境中的應用提供了先天的便利。

2.6.4 Pool

  • Pool是存儲對象的邏輯分區,它規定了資料備援的類型和對應的副本分布政策,支援兩種類型:副本(replicated)和 糾删碼( Erasure Code)。

2.6.5 PG

  • PG( placement group)是一個放置政策組,它是對象的集合,該集合裡的所有對象都具有相同的放置政策,簡單點說就是相同PG内的對象都會放到相同的硬碟上,PG是 ceph的邏輯概念,服務端資料均衡和恢複的最小粒度就是PG,一個PG包含多個OSD。引入PG這一層其實是為了更好的配置設定資料和定位資料。

2.6.6 Object

  • 簡單來說塊存儲讀寫快,不利于共享,檔案存儲讀寫慢,利于共享。能否弄一個讀寫快,利于共享的出來呢。于是就有了對象存儲。最底層的存儲單元,包含中繼資料和原始資料。

2.7 Ceph核心元件

2.7.1 Monitor (ceph-mon)

  • 一個Ceph叢集需要多個Monitor組成的小叢集,它們通過Paxos同步資料,用來儲存OSD的中繼資料。負責監視整個Ceph叢集運作的Map視圖(如OSD Map、Monitor Map、PG Map和CRUSH Map),維護叢集的健康狀态,維護展示叢集狀态的各種圖表,管理叢集用戶端認證(認證使用cephx協定)與授權。通常至少需要三個螢幕才能實作備援和高可用性。

2.7.2 Managers(ceph-mgr)

  • 在一個主機上運作的一個守護程序。ceph manager守護程式負責跟蹤運作時名額和ceph叢集的目前狀态,包括存儲使用率,目前性能名額和系統負載。ceph manager 守護程式還托管基于python的子產品來管理和公開ceph叢集資訊,包括基于web的ceph儀表盤和REST API 為外界提供統一的入口。高可用性通常至少需要兩個管理器。

2.7.3 OSD(對象存儲守護程式ceph-osd)

  • OSD是負責實體存儲的程序,作業系統上的一個磁盤就是一個OSD守護程式,OSD用于處理ceph叢集資料複制,恢複,重新平衡,并通過檢查其他ceph OSD守護程式的心跳來向ceph螢幕和管理器提供一些監視資訊。通常至少需要3個ceph OSD才能實作備援和高可用性。
  • Pool、PG和OSD的關系:
  • 一個Pool裡有很多PG;
  • 一個PG裡包含一堆對象,一個對象隻能屬于一個PG;
  • PG有主從之分,一個PG分布在不同的OSD上(針對三副本類型);

2.7.4 MDS(ceph中繼資料伺服器 ceph-mds)

  • MDS全稱Ceph Metadata Server,是CephFS服務依賴的中繼資料服務。負責儲存檔案系統的中繼資料,管理目錄結構。對象存儲和塊裝置存儲不需要中繼資料服務。

2.7.5 RBD

  • RBD全稱RADOS block device,是Ceph對外提供的塊裝置服務。

2.7.6 RGW

  • RGW全稱RADOS gateway,是Ceph對外提供的對象存儲服務,接口與S3和Swift相容。

2.7.7 CephFS

  • CephFS全稱Ceph File System,是Ceph對外提供的檔案系統服務。

2.8 Ceph中繼資料儲存方式

  • 對象資料的中繼資料以key-value的形式存在,在RADOS中有兩種實作:xattrs和omap。
  • ceph可選後端支援多種存儲引擎,比如filestore,bluestore,kvstore,memstore,ceph使用bluestore存儲對象資料的中繼資料資訊。

2.8.1 xattrs(擴充屬性)

  • 是将中繼資料儲存在對象對應檔案的擴充屬性中并儲存到系統磁盤上,這要求支援對象存儲的本地文系統(一般是XFS)支援擴充屬性。

2.8.2 omap(object map對象映射)

  • omap:是object map的簡稱,是将中繼資料儲存在本地檔案系統隻外的獨立key-value存儲系統中,在使用filestore時是leveldb,在使用bluestore時是rocksdb,由于filestore存在功能問題(需要将磁盤格式化為XFS格式)及中繼資料高可用問題等,是以ceph(Luminous 12.2.z 版本開始)主要使用bluestore。

2.8.2.1 filestore與leveldb

  • ceph(Luminous 12.2.z 版本之前)早期基于filestore使用google的levelDB儲存對象的中繼資料,LevelDb是一個持久化存儲的kv系統,和Redis這種記憶體型的kv系統不同,leveldb不會像Redis一樣将資料放在記憶體進而占用大量的記憶體空間,而是将大部分資料存儲到磁盤上,但是需要把磁盤上的leveldb空間格式化為檔案系統(XFS)。
  • Filestore将資料儲存到與Posix相容的檔案系統(Btrfs,XFS,ext4)。在ceph後端使用傳統的linux檔案系統盡管提供了一些好處,但也有代價,如性能、對象屬性與磁盤本地檔案系統屬性比對存在限制等。

2.8.2.2 bluestore與rocksdb

  • 由于leveldb依然需要磁盤檔案系統支援,後去facebok對levelDB進行改進為​​RocksDB​​, RocksDB将對象資料的中繼資料儲存在RocksDB,ceph對象資料放在了每個OSD中,那麼就在目前OSD中劃分出一部分空間,格式化為BlueFS檔案系統用于儲存RocksDB中的中繼資料資訊(成為Bluestore),并實作中繼資料的高可用,BlueStore最大的特點是建構在裸磁盤裝置之上,并且對諸如SSD等新的儲存設備做了很多優化工作。
  • 對全SSD及全NVMe SSD閃存适配。
  • 繞過本地檔案系統層,直接管理裸裝置,縮短IO路徑。
  • 嚴格分離中繼資料和資料,提高索引效率。
  • 使用kv索引,解決檔案系統目錄結構周遊效率低的問題。
  • 支援多種裝置類型。
  • 解決日志“雙寫”問題。
  • 期望帶來至少2倍的寫性能提升和同等讀性能。
  • 增加資料校驗及資料壓縮等功能。
  • RocksDB通過中間層BlueRocksDB通路檔案系統的接口。這個檔案系統與傳統的linux檔案系統(ext4和XFS)是不同的,它不是在VFS下面的通用檔案系統,而是一個使用者态的邏輯。BlueFS通過函數接口(API,非POSIX)的方式為BlueRocksDB提供類似檔案系統的能力。
  • Allocator:負責裸裝置的空間管理配置設定。
  • RocksDB:rocksdb是facebook基于leveldb開發的一款kv資料庫,BlueStore将中繼資料全部存放至RocksDB中,這些中繼資料包括存儲預寫式日志、資料對象中繼資料、ceph的omap資料資訊以及配置設定器的中繼資料。
  • BlueRocksEnv:這是RocksDB與BlueFS互動的接口,RocksDB提供了檔案操作的接口EnvWrapper(Env封裝器)可以通過繼承實作該接口來自定義底層的讀寫操作,BlueRocksEnv就是繼承自EnvWrapper實作對BlueFS的讀寫。
  • BlueFS:BlueFS是BlueStore針對RocksDB開發的輕量級檔案系統,用于存放RocksDB産生的.sst和.log等檔案。
  • BlockDevice:BlueStore抛棄了傳統的ext4、xfs檔案系統,使用直接管理裸磁盤的方式;BlueStore支援同時使用多種不同類型的裝置,在邏輯上BlueStore将存儲空間劃分為三層:慢速(Slow)空間、告訴(DB)空間、超高速(WAL)空間,不同的空間可以指定使用不同的裝置類型,當然也可以使用同一塊裝置。
  • BlueStore的設計考慮了FileStore中存在的一些硬傷,抛棄了傳統的檔案系統直接管理裸裝置,縮短了IO路徑,同時采用了ROW的方式,避免了日志雙寫的問題,在寫入性能有了極大的提高。

2.9 Ceph CRUSH算法

  • Controllers replication under scalable hashing #可控的、可複制的、可伸縮的一緻性hash算法。
  • ceph使用CRUSH算法來存放和管理資料,它是ceph的智能資料分發機制。ceph使用CRUSH算法來準确計算資料應該被儲存到哪裡,以及應該從哪裡讀取資料和儲存中繼資料,不用的是CRUSH是按需計算出中繼資料,是以它就消除了對中心式的伺服器/網關的需求,它使得ceph用戶端能夠計算出中繼資料,改過程也稱為CRUSH查找,然後和OSD直接通信。
  1. 如果把對象直接映射到OSD之上會導緻對象與OSD的對應關系過于緊密和耦合,當OSD由于故障發生變更時将會對整個ceph叢集産生影響。
  2. 于是ceph将一個對象映射到RADOS叢集的時候分為兩步走。
  1. 首先使用一緻性hash算法将對象名稱映射到PG 2.7。
  2. 然後在PG ID基于CRUSH算法映射到OSD即可查找對象。
  1. 以上兩個過程都是以實時計算的方式完成,而沒有使用傳統的查詢資料與塊裝置的對應表的方式,這樣有效避免了元件的中心化問題,也解決了查詢性能和備援問題。使得ceph叢集擴充不在收查詢的性能限制。
  2. 這個實時計算操作使用的就是CRUSH算法。
  • Controllers replication under scalable hashing #可控的、可複制的、可伸縮的一緻性hash算法。
  • CRUSH是一種分布式算法,類似于一緻性hash算法,用于為RADOS存儲叢集控制資料配置設定。

2.10 Ceph的管理節點

  • ceph常用管理接口是一組指令行工具程式,例如rados、ceph、rbd等指令,ceph管理者可以從摸個特定的ceph-mon節點執行管理操作。
  • 推薦使用部署專用的管理節點對ceph進行配置管理、更新與後期維護,友善後期權限管理,管理節點的權限支隊管理人員開放,可以避免一些不必要的誤操作發生。

2.11 Ceph叢集部署方法

2.11.1 官方文檔

  • https://github.com/ceph/ceph   #github倉庫
  • http://docs.ceph.org.cn/install/manual-deployment/   #簡要部署過程
  • https://docs.ceph.com/en/latest/releases/index.html   #版本曆史
  • https://docs.ceph.com/en/latest/releases/pacific/#v16-2-0-pacific  #ceph 16 即 Pacific 版本支援的系統
  • CentOS 8
  • Ubuntu 20.04 (Focal)
  • Ubuntu 18.04 (Bionic)
  • Debian Buster
  • Container image (based on CentOS 8)

2.11.2 官方推薦

  • ​​Cephadm​​
  • 使用容器和 systemd 安裝和管理 Ceph 叢集,并與 CLI 和儀表闆 GUI 緊密內建。
  • cephadm 僅支援 Octopus 和更新版本。
  • cephadm 與新的編排 API 完全內建,并完全支援新的 CLI 和儀表闆功能來管理叢集部署。
  • cephadm 需要容器支援(podman 或 docker)和 Python 3。
  • ​​Rook​​
  • 部署和管理在 Kubernetes 中運作的 Ceph 叢集,同時還支援通過 Kubernetes API 管理存儲資源和配置。我們推薦 Rook 作為在 Kubernetes 中運作 Ceph 或将現有 Ceph 存儲叢集連接配接到 Kubernetes 的方式。
  • Rook 僅支援 Nautilus 和更新版本的 Ceph。
  • Rook 是在 Kubernetes 上運作 Ceph 或将 Kubernetes 叢集連接配接到現有(外部)Ceph 叢集的首選方法。
  • Rook 支援新的 Orchestrator API。完全支援 CLI 和儀表闆中的新管理功能。

2.11.3 其它方法

  • ceph-ansible: https://github.com/ceph/ceph-ansible #python
  • ceph-salt: https://github.com/ceph/ceph-salt #python
  • ceph-container: https://github.com/ceph/ceph-container #shell
  • ceph-chef: https://github.com/ceph/ceph-chef #Ruby
  • ceph-deploy: https://github.com/ceph/ceph-deploy #python
  • Ceph-deploy是一個ceph官方維護的基于ceph-deploy指令行部署ceph叢集的工具,基于ssh執行可以sudo權限的shell指令以及一些python腳本實作ceph叢集的部署和管理維護。
  • Ceph-deploy 隻用于部署和管理ceph叢集,用戶端需要通路ceph,需要部署用戶端工具。
  • Ceph-deploy v2.0.1版本不相容python 3.7+

2.12 Ceph 的版本曆史

  • x.0.z - 開發版(給早期測試者和勇士們) 9.0.0->9.0.1->9.0.2 等。
  • x.1.z - 候選版(用于測試叢集、 高手們)9.1.0->9.1.1->9.1.2 等。
  • x.2.z - 穩定、 修正版(給使用者們) 9.2.0->9.2.1->9.2.2 等。