久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Ceph QoS初探(下)

 hello_worldw6 2017-08-23

存儲QoS是個可以做很大也可以做很小的特性。SolidFire認(rèn)為將QoS歸類為特性太兒戲,,QoS應(yīng)該是存儲系統(tǒng)設(shè)計(jì)之初就要仔細(xì)考慮的架構(gòu)問題,。的確,,分析了一眾主流存儲大廠后還是覺得它在這方面做得最細(xì)致最全面。同時也有些廠商做得比較簡陋,,只提供了帶寬或者IOPS的限速功能,。這或許在某些場景中已經(jīng)夠用,但我認(rèn)為一個完整的QoS方案至少要包括對帶寬,、IOPS的預(yù)留,、上限和優(yōu)先級控制,如果再精細(xì)點(diǎn)還可以考慮IO的粒度,、延遲,、突發(fā)、空間局部性,、系統(tǒng)內(nèi)部IO,、用戶IO、緩存,、磁盤等要素,。

分布式存儲都有很長的IO路徑,簡單的IOPS限速功能通常在路徑的最前端實(shí)現(xiàn),。例如OpenStack Cinder默認(rèn)使用QEMU完成存儲塊的限速功能,,QEMU對存儲來說已經(jīng)屬于客戶端的角色了。

QoS的本質(zhì)總結(jié)起來就四個字:消此長彼,,它并不會提高系統(tǒng)整體處理能力,,只是負(fù)責(zé)資源的合理分配。據(jù)此就可以提出一連串問題了:首先,,如何知道什么時候該消誰什么時候該長誰,?其次,該怎么消該怎么長,?這兩個問題QoS算法可以幫忙解決,,可以參考我的另外一篇文章《聊聊dmclock算法》。在這兩個問題之前還需要選擇一塊風(fēng)水寶地,,能夠控制希望可以控制的IO,,否則即使知道何時控制以及如何控制也鞭長莫及無能為力。風(fēng)水寶地的選擇可以參考我的另外一篇文章《拆開Ceph看線程和隊(duì)列》,。

對Ceph來說,,OSD的ShardedOpWq隊(duì)列是個不錯的選擇,因?yàn)閹缀跛兄亓考壍腎O都會經(jīng)過該隊(duì)列,。這些IO可以劃分為兩大類,,一類是客戶端過來的IO,包括文件,、對象和塊存儲,;另一類是系統(tǒng)內(nèi)部活動產(chǎn)生的IO,包括副本復(fù)制,、Scrub,、Recovery和SnapTrim等。第一類IO由于涉及到一些敏感內(nèi)容暫不考慮,,本文主要分析第二類IO,,這也是本文叫做下篇的原因。

Recovery

配置項(xiàng) 默認(rèn)值 說明
osd_recovery_threads 1 Recovery線程池中線程的個數(shù)
wipe_dmclock2分支已經(jīng)禁用該線程池
osd_max_backfills 1 同時進(jìn)行恢復(fù)的PG數(shù)目的最大值
osd_min_recovery_priority 0 優(yōu)先級最高為255, 基數(shù)為230,??赏ㄟ^命令行配置PG的優(yōu)先級
osd_recovery_max_active 3
osd_recovery_max_single_start 1 一個PGRecovery對應(yīng)的Object個數(shù)
osd_recovery_delay_start 0 推遲Recovery開始時間
osd_recovery_sleep 0 出隊(duì)列后先Sleep一段時間,拉長兩個Recovery的時間間隔
osd_recovery_op_priority 3 Recovery Op的優(yōu)先級
osd_max_push_cost 8^20 MOSDPGPush消息的大小
osd_max_push_objects 10 MOSDPGPush消息允許的Object數(shù)量
osd_recovery_cost 20MB 入ShardOpWq隊(duì)列時配置,,待補(bǔ)充
osd_recovery_priority 5 入ShardOpWq隊(duì)列時配置,,待補(bǔ)充

Recovery自己已經(jīng)具備了一些優(yōu)先級控制的功能,上表給出了一些控制參數(shù),,下面一一介紹下每個參數(shù)的作用,。

Ceph主線分支中Recovery擁有獨(dú)立的工作隊(duì)列和線程池,線程池的線程數(shù)目由配置項(xiàng)osd_recovery_threads指定,,默認(rèn)為1,。Ceph wip_dmclock2分支取消了Recovery的工作隊(duì)列和線程池,轉(zhuǎn)而將Recovery Op入ShardOpWq隊(duì)列,。這樣Recovery Op和其它類型Op在相同的隊(duì)列,,因此理論上會有更好的控制效果。

預(yù)留

OSDService
    |-- remote_reserver: AsyncReserver<spg_t>
    |-- local_reserver: AsyncReserver<spg_t>
        |-- queues: map<unsigned, list<pair<T, Context*> > >  // Key為pg恢復(fù)的優(yōu)先級,,Value為List,,List元素為<pgid, QueuePeeringEvt>
        |-- queue_pointers: map<T, pair<unsigned, typename list<pair<T, Context*> >::iterator > >  // Key為pgid,Value為queues[prio]
        |-- in_progress: set<T>  // 正在處理的請求
        |-- f: Finisher  // 調(diào)用queues中Context的隊(duì)列
        |-- max_allowed: unsigned  // osd_max_backfills配置項(xiàng)
        |-- min_priority: unsigned  // osd_min_recovery_priority配置項(xiàng)

1. WaitLocalRecoveryReserved::WaitLocalRecoveryReserved() --> AsyncReserver::request_reservation() --> AsyncReserver::do_queues()
2. QueuePeeringEvt::finish() --> PG::queue_peering_event(LocalRecoveryReserved)  // 由AsyncReserver的Finish線程調(diào)用

在開始恢復(fù)數(shù)據(jù)前Ceph會先進(jìn)行預(yù)留,,預(yù)留的其中一個目的是控制不同PG恢復(fù)的優(yōu)先級,。預(yù)留通過AsyncReserver類實(shí)現(xiàn),該類包含了一個優(yōu)先級隊(duì)列queues,,預(yù)留時先將PG入優(yōu)先級隊(duì)列,,再根據(jù)PG的優(yōu)先級從高到低的順序出隊(duì)列,優(yōu)先級越高的PG越先恢復(fù),。雖然AsyncReserver以PG為單位進(jìn)行優(yōu)先級控制,,但事實(shí)上用戶以Pool為單位設(shè)置PG的優(yōu)先級。Ceph的ceph osd pool set recovery_priority命令用于設(shè)置Pool的Recovery優(yōu)先級,,屬于同個Pool的PG具有相同的優(yōu)先級,。

預(yù)留的另一個目的是控制OSD中同時進(jìn)行恢復(fù)的PG數(shù)目。AsyncReserver::max_allowed限制PG出隊(duì)列,,若正在處理的PG數(shù)目超過max_allowed則后面的請求將留在隊(duì)列內(nèi)直到其它PG完成恢復(fù)后才出隊(duì)列,。預(yù)留會同時考慮Primary OSD和Replica OSD,,Primary OSD通過local_reserver來預(yù)留,Replica OSD通過remote_reserver來預(yù)留,,默認(rèn)每個AsyncReserver同一個時刻只允許一個PG進(jìn)行恢復(fù),。因?yàn)橐粋€OSD同時為某些PG的Primary為另一些PG的Replica,所以一個OSD同一時刻只允許兩個PG進(jìn)行恢復(fù),。

恢復(fù)

PGRecovery
    |-- reserved_pushes: uint64_t

OSDService
    |-- awaiting_throttle: list<pair<epoch_t, PGRef> >
    |-- recovery_ops_reserved: uint64_t  // 預(yù)留的ops,,進(jìn)ShardOp隊(duì)列的recovery請求數(shù)
    |-- recovery_ops_active: uint64_t
    |-- defer_recovery_until: utime_t  //  允許Recovery啟動的時間
    |-- recovery_paused: bool  // 暫停Recovery,通過OSDMap來設(shè)置

// 狀態(tài)機(jī)進(jìn)入Recoverying狀態(tài),,將PGRecovery Op入ShardOpWq隊(duì)列
Recovering::Recovering() --> PG::queue_recovery(false) --> OSDService::_maybe_queue_recovery() --> OSDService::_queue_for_recovery() --> ShardedWQ::queue(PGRecovery)

RPGHandle(PGBackend::RecoveryHandle)
    |-- pushes: map<pg_shard_t, vector<PushOp>>  // pg_shard_t目標(biāo)OSD,,PushOp Object的詳細(xì)內(nèi)容
    |-- pulls: map<pg_shard_t, vector<PullOp>>  // pg_shard_t目標(biāo)OSD,PullOp Object的詳細(xì)內(nèi)容

MOSDPGPush
    |-- pushes: vector<PushOp>

// 出ShardOpWq隊(duì)列
PGQueueable::RunVis::operator() --> OSD::do_recovery() --> ReplicatedPG::start_recovery_ops() --> ReplicatedPG::recover_replicas() -->
1. ReplicatedPG::prep_object_replica_pushes() --> ReplicatedBackend::recover_object() --> ReplicatedBackend::start_pushes() --> ReplicatedBackend::prep_push_to_replica() --> ReplicatedBackend::prep_push()
2. ReplicatedBackend::run_recovery_op() --> ReplicatedBackend::send_pushes()

回顧下前端IO控制,,在3副本情況下一個前端MOSDOp請求將衍生出兩個額外的MOSDRepOp請求,,而mClock隊(duì)列只控制MOSDOp請求的速度,通過MOSDOp來間接控制MOSDRepOp請求,。Recovery也采用類似的策略,,mClock隊(duì)列控制PGRecovery出隊(duì)列的速度,而每個PGRecovery可能對應(yīng)多個Object的恢復(fù),,通過PGRecovery間接控制Object的恢復(fù),。

除了在mClock隊(duì)列中控制PGRecovery速度外,Ceph還提供了多種手段來控制PGRecovery到Object的映射關(guān)系,。首先,,限制每個PGRecovery對應(yīng)的Object的數(shù)目,由osd_recovery_max_single_start配置決定,,默認(rèn)為1,。也就說,每個PGRecovery默認(rèn)只能恢復(fù)一個Object,。其次,,限制活動的Object恢復(fù)操作,由osd_recovery_max_active配置決定,。Ceph將恢復(fù)Op分為兩類:一類是Active恢復(fù)操作代表已經(jīng)正在恢復(fù)的操作,;另一類是預(yù)留的恢復(fù)操作,代表正在mClock隊(duì)列等候的PGRecovery對應(yīng)的恢復(fù)操作,。當(dāng)PGRecovery入mClock隊(duì)列時,,根據(jù)這兩類操作數(shù)以及osd_recovery_max_active來限制PGRecovery允許的Object個數(shù)。最后限制恢復(fù)請求中對象的個數(shù)和大小,,由osd_max_push_costosd_max_push_objects兩個配置決定,。

// Replica處理MOSDPGPush消息
1. OSD::dispatch_op_fast() --> OSD::handle_replica_op() --> OSD::enqueue_op() --> PG::queue_op() --> ShardedWQ::queue()
2. ReplicatedPG::do_request() --> ReplicatedBackend::handle_message() --> ReplicatedBackend::do_push() --> ReplicatedBackend::_do_push()

// Primary處理MOSDPGPushReply消息
3. ReplicatedPG::do_request() --> ReplicatedBackend::handle_message() --> ReplicatedBackend::do_push_reply() --> ReplicatedBackend::handle_push_reply() --> ReplicatedPG::on_global_recover() --> PG::finish_recovery_op() --> OSDService::finish_recovery_op() --> OSDService::_maybe_queue_recovery()

一個Recovery Object的所有Replica都恢復(fù)后,Primary重新向ShardOp隊(duì)列投遞PGRecovery請求,,ShardOp線程開始下個Object的恢復(fù),。所有Object都恢復(fù)后ShardOp線程使用AllReplicasRecovered事件將狀態(tài)機(jī)從Recovering狀態(tài)切換到Recovered狀態(tài),,同時釋放Replica的預(yù)留。最后,,如果所有節(jié)點(diǎn)都Active,,則從Recovered狀態(tài)切換到Clean狀態(tài)。

(Deep)Scrub

配置項(xiàng) 默認(rèn)值 說明
osd_scrub_chunk_min 5 PGScrub對應(yīng)的Object數(shù)目的最小值
osd_scrub_chunk_max 25 PGScrub對應(yīng)的Object數(shù)目的最大值
osd_deep_scrub_interval 1周 Deep scrub周期
osd_scrub_sleep 0 兩個PGScrub Op間休息一段時間
osd_heartbeat_interval 6 周期性執(zhí)行OSD::sched_scrub函數(shù)
osd_scrub_begin_hour 0 允許觸發(fā)Scrub的時間段的起始時間
osd_scrub_end_hour 0 允許觸發(fā)Scrub的時間段的結(jié)束時間,,結(jié)束時間可以小于起始時間
osd_scrub_auto_repair false 自動repair不一致Object,不支持副本池,,只支持EC池
osd_max_scrubs 1 OSD允許同時運(yùn)行的Scrub任務(wù)的最大數(shù)目
osd_scrub_min_interval 60*60*24 一天
osd_scrub_max_interval 7*60*60*24 一周
osd_scrub_interval_randomize_ratio 0.5 [min, min*(1+randomize_ratio)]
osd_scrub_during_recovery true 允許在OSD Recovery過程中執(zhí)行Scrub任務(wù)
osd_scrub_load_threshold 0.5 只有負(fù)載低于該值時才允許觸發(fā)Scrub

同前端IO和Recovery一樣,,Ceph通過控制PGScrub來間接控制Scrub的所有IO優(yōu)先級。

啟動

OSDService
    |-- sched_scrub_pg: set<ScrubJob>  // 已注冊的Scrub任務(wù)
        |-- sched_time: utime_t  // 任務(wù)開始執(zhí)行的時間
        |-- deadline: utime_t

// 注冊ScrubJob
PG::reg_next_scrub()  --> OSD::reg_pg_scrub() --> OSD::sched_scrub_pg

// 調(diào)度ScrubJob
OSD::init() --> C_Tick_WithoutOSDLock::finish() --> OSD::tick_without_osd_lock() --> OSD::sched_scrub() --> PG::sched_scrub() --> PG::queue_scrub() --> PG::requeue_scrub() --> OSD::queue_for_scrub()

Ceph以PG為單位執(zhí)行Scrub操作,,若要執(zhí)行Scrub操作事先需要以ScrubJob的形式向OSD注冊,,OSD會定時檢查注冊的ScrubJob,若條件滿足則開始執(zhí)行Scrub操作,。這涉及到兩個問題:第一個問題是何時注冊ScrubJob,,第二個問題是何時執(zhí)行ScrubJob。執(zhí)行PGLog合并,、PG分裂,、Scrub相關(guān)命令時都會注冊ScrubJob,每個ScrubJob包含一個任務(wù)開始時間(sched_time)和一個最終時間(deadline),。默認(rèn)情況下,,ScrubJob::sched_time小于當(dāng)前時間+osd_scrub_min_interval,ScrubJob::deadline為當(dāng)前時間+osd_scrub_max_interval,,注冊任務(wù)后正常情況在一天內(nèi)執(zhí)行,,特殊情況一周內(nèi)執(zhí)行。

OSD進(jìn)程啟動時初始化C_Tick_WithoutOSDLock定時器,,定時器默認(rèn)每隔18秒檢查一次OSD中已注冊的ScrubJob,,對滿足條件的ScrubJob開始執(zhí)行預(yù)留操作。檢查的內(nèi)容包括以下幾項(xiàng):

  • 檢查是否到達(dá)ScrubJob的開始時間(sched_time),,沒到達(dá)不執(zhí)行,;
  • 在有Recovery Op的情況下,檢查 osd_scrub_during_recovery配置是否允許同時執(zhí)行Scrub任務(wù),;
  • 檢查PG是否為Active狀態(tài),,非Active不允許執(zhí)行;
  • 檢查ScrubJob是否超期(deadline),;
  • 檢查當(dāng)前時間是否位于允許Scrub的時間段內(nèi)并且系統(tǒng)負(fù)載也在允許范圍內(nèi),。

特別注意在ScrubJob已經(jīng)超期的情況下將忽略最后一個限制條件強(qiáng)制執(zhí)行Scrub任務(wù)。另外值得一提的是Scrub時間段,,它由osd_scrub_begin_hour和osd_scrub_end_hour兩個配置項(xiàng)控制,。osd_scrub_begin_hour可以小于也可以大于osd_scrub_end_hour,,它們兩的取值范圍都是0到24。當(dāng)osd_scrub_begin_hour小于osd_scrub_end_hour時,,允許時間段為[osd_scrub_begin_hour, osd_scrub_end_hour],;當(dāng)osd_scrub_begin_hour大于osd_scrub_end_hour時,允許的時間段為[osd_scrub_begin_hour, 24]和[0, osd_scrub_end_hour]兩部分,。因?yàn)?和24是重疊的,,所以實(shí)際上這兩個時間段是連續(xù)的。

預(yù)留

PG
    |-- scrubber: Scrubber
        |-- reserved: bool  // 是否已預(yù)留
        |-- reserve_failed: bool // 預(yù)留失敗,,只要一個Peer預(yù)留失敗就代表預(yù)留失敗
        |-- reserved_peers: set<pg_shard_t>  // 預(yù)留成功的Peer OSD

OSD
    |-- scrubs_pending: int  // 排隊(duì)的Scrub任務(wù)數(shù)目
    |-- scrubs_active: int  // 運(yùn)行的Scrub任務(wù)數(shù)目

// Replica處理預(yù)留請求
ReplicatedPG::do_request() --> ReplicatedPG::do_sub_op() --> PG::sub_op_scrub_reserve() --> OSDService::inc_scrubs_pending()

// Primary處理預(yù)留回復(fù)
ReplicatedPG::do_request() --> ReplicatedPG::do_sub_op_reply() --> PG::sub_op_scrub_reserve_reply() --> PG::sched_scrub()

ScrubJob滿足調(diào)度條件后開始執(zhí)行Scrub前需要向PG的所有OSD節(jié)點(diǎn)申請預(yù)留,,只有預(yù)留成功后才允許開始Scrub操作。預(yù)留的目的是為了限制OSD進(jìn)程內(nèi)同時進(jìn)行Scrub任務(wù)的個數(shù),。Ceph將Scrub任務(wù)的狀態(tài)劃分為兩類:一類是已經(jīng)在運(yùn)行,,另一類是正在預(yù)留階段還沒開始執(zhí)行的。只有這兩類的Scrub任務(wù)總數(shù)低于osd_max_scrubs配置時才能夠預(yù)留成功,。osd_max_scrubs默認(rèn)值為1,,也就是說OSD進(jìn)程同一時刻最多只能運(yùn)行一個Scrub任務(wù)。 只有PG的所有OSD節(jié)點(diǎn)都預(yù)留成功后,,Ceph才開始向mClock隊(duì)列投遞PGScrub Op開始真正的Scrub操作,。

比較

PG
    |-- scrubber: Scrubber
        |-- store: std::unique_ptr<Scrub::Store>
        |-- waiting_on: int  // 未完成Scrub的Secondary OSD的數(shù)目
        |-- waiting_on_whom: set<pg_shard_t>  // 未完成Scrub的Secondary OSD
        |-- received_maps: map<pg_shard_t, ScrubMap>  // Secondary OSD的ScrubMap
        |-- subset_last_update: eversion_t  // 影響chunk中object的最近的版本號
        |-- active_rep_scrub: OpRequestRef  // (備OSD)等待subset_last_update版本完成
        |-- queue_snap_trim: bool  // Scrub結(jié)束后執(zhí)行SnapTrim,也就是說,,Scrub和SnapTrim不能同時執(zhí)行

PGQueueable::RunVis::operator(PGScrub) --> PG::scrub() --> PG::chunky_scrub()

執(zhí)行Scrub操作的主要邏輯:首先選出一組Object,,Object的個數(shù)由osd_scrub_chunk_min和osd_scrub_chunk_max兩個配置決定;然后向PG的其它OSD節(jié)點(diǎn)請求ScrubMap,;接收到所有Peer OSD節(jié)點(diǎn)的ScrubMap后進(jìn)行比較,。同Recovery一樣,此處要考慮一個PGScrub Op和Object的對應(yīng)關(guān)系,。

SnapTrim

配置項(xiàng) 默認(rèn)值 說明
osd_snap_trim_cost 1MB
osd_snap_trim_priority 5
osd_snap_trim_sleep 0 兩次PGSnapTrim請求間休眠時間
osd_pg_max_concurrent_snap_trims 2 每個PGSnapTrim對應(yīng)的Object數(shù)目

客戶端刪除快照

從客戶端來說,,快照整體上應(yīng)該同時包含RBD塊快照和CephFS快照兩種類型,本節(jié)只考慮RBD塊的快照,。RBD塊的快照數(shù)據(jù)包含兩部分內(nèi)容:一部分是存儲塊級別的快照元數(shù)據(jù),,保存在header對象的OMAP;另一部分是Object級別的快照信息,,這部分又由保存在Object屬性中的快照元數(shù)據(jù)和Clone Object兩部分內(nèi)容構(gòu)成,。Ceph刪除這兩部分內(nèi)容的方式不同。

// RBD客戶端向OSD發(fā)送刪除快照的消息
rbd::Shell::execute() --> rbd::action::snap::execute_remove() --> rbd::action::snap::do_remove_snap() --> librbd::Image::snap_remove2() --> librbd::snap_remove() --> librbd::Operations<librbd::ImageCtx>::snap_remove() --> Operations<I>::snap_remove() --> librbd::Operations<librbd::ImageCtx>::execute_snap_remove() --> librbd::operation::SnapshotRemoveRequest::send() --> cls_client::snapshot_remove() --> ... --> 發(fā)送op給rbd_header對象所在的Primary OSD

// OSD刪除快照信息
cls_rbd::snapshot_remove() --> cls_cxx_map_remove_key() --> ReplicatedPG::do_osd_ops(CEPH_OSD_OP_OMAPRMKEYS)

// RBD客戶端向Monitor發(fā)送刪除快照的消息
librbd::operation::SnapshotRemoveRequest::send() --> SnapshotRemoveRequest<I>::send_release_snap_id() --> Objecter::delete_selfmanaged_snap() --> 
Objecter::pool_op_submit() --> Objecter::_pool_op_submit() --> MonClient::send_mon_message()

// Monitor刪除快照信息
OSDMonitor::prepare_pool_op() --> pg_pool_t::remove_unmanaged_snap() --> pg_pool_t::removed_snaps

對第一部分內(nèi)容,,RBD客戶端直接向header對象所在的Primary OSD發(fā)送CEPH_OSD_OP_OMAPRMKEYS消息,,立即刪除。對第二部分內(nèi)容,Ceph采用異步策略:先向Monitor節(jié)點(diǎn)發(fā)送刪除快照的請求,,Monitor回復(fù)后客戶端即可退出,,宣告快照已被刪除。同時,,Monitor修改OSDMap中和快照相關(guān)的數(shù)據(jù)構(gòu)建OSDMap增量,,并在適當(dāng)?shù)臅r候?qū)⑿掳鍻SDMap分發(fā)給相關(guān)OSD節(jié)點(diǎn),OSD節(jié)點(diǎn)接收到新OSDMap后獲得待刪除快照,,從而開始刪除Object級別的快照信息,。

ReplicatedPG(PG)
    |-- snap_trimq: interval_set<snapid_t>  // 待刪除的快照列表
    |-- pool: PGPool
        |-- cached_removed_snaps: interval_set<snapid_t>  // 總的快照列表
        |-- newly_removed_snaps: interval_set<snapid_t>  // 一次更新中,新產(chǎn)生的待刪除快照列表

// OSD處理MOSDMap消息,,掃描PG向Peering隊(duì)列投遞NullEvt事件
OSD::handle_osd_map() --> C_OnMapCommit::finish() --> OSD::_committed_osd_maps() --> OSD::consume_map() --> PG::queue_null() --> PG::queue_peering_event()

// OSD Peer工作線程處理NullEvt事件
OSD::process_peering_events() --> OSD::advance_pg() --> PG::handle_advance_map() --> 
1. PGPool::update()  // 更新PGPool中待刪除的快照列表
2. RecoveryState::handle_event(AdvMap) --> RecoveryState::Active::react(AdvMap)--> ReplicatedPG::kick_snap_trim() --> SnapTrimmer::process_event(KickTrim)  // 更新snap_trimq,,通知狀態(tài)機(jī)開始刪除快照對象

OSD分別在PG::snap_trimq和PGPool中保持了待刪除快照列表,真正開始刪除數(shù)據(jù)時從PG::snap_trimq中取快照,。為什么要在兩個地方保存待刪除快照?估計(jì)考慮到了PG Recovery的不同狀態(tài),,在PG切換到Active狀態(tài)時會將PGPool中的待刪除列表賦值給snap_trimq,。如果更新OSDMap時,PG恰好處于Active狀態(tài)那么將同時更新PGPool和snap_trimq,。上面給出了更新OSDMap時更新待刪除快照列表的流程,。

OSD刪除快照數(shù)據(jù)

ReplicatedPG(PG)
    |-- snap_trimmer_machine: SnapTrimmer
    |    |-- NotTrimming  // 狀態(tài)機(jī)初始狀態(tài)
    |    |-- AwaitAsyncWork  // 工作狀態(tài)
    |    |-- WaitRWLock
    |    |-- WaitScrub  // 等待Scrub結(jié)束
    |    |-- WaitRepops  // 等待Replica完成快照對象刪除
    |-- snap_trimq: interval_set<snapid_t>  // 待刪除的快照列表
    |-- snap_mapper: SnapMapper

// PGSnapTrim入ShardedOpWq隊(duì)列
AwaitAsyncWork::AwaitAsyncWork() --> OSDService::queue_for_snap_trim()

// PGSnapTrim出ShardedOpWq隊(duì)列
PGQueueable::RunVis::operator(PGSnapTrim) --> ReplicatedPG::snap_trimmer() --> AwaitAsyncWork::react(DoSnapWork) --> ReplicatedPG::simple_opc_submit() --> ReplicatedPG::issue_repop() --> ReplicatedBackend::submit_transaction() --> ReplicatedBackend::issue_op()

同Recovery、Scrub一樣,,SnapTrim也是通過控制PGSnapTrim來間接控制快照刪除的整體速度,。一個SnapTrim默認(rèn)對應(yīng)刪除兩個對象的快照,由osd_pg_max_concurrent_snap_trims配置決定,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多