primarylogpg::do_op(oprequestref& op)
|---
if (m->finish_decode()) //解碼什麼?
|---hobject_t head = m->get_hobj()
// info.pgid.pgid.get_split_bits = unsigned pg_t::get_split_bits(unsigned pg_num) const pg處於**狀態?
|---
if (m->has_flag(ceph_osd_flag_parallelexec)) //並行執行狀態,直接返回失敗
|---osd->reply_op_error(op, -einval); return
|---
if (op->rmw_flags ==
0) |---int r = osd->osd->init_op_flags(op)
|---
|---
|---
if ( r )
|---osd->reply_op_error(op, r); return
|---
if ((m->get_flags() & (ceph_osd_flag_balance_reads | ceph_osd_flag_localize_reads)) &&
op->may_read() &&
!(op->may_write() || op->may_cache())) //此時只有副本才能執行操作
|---handle_misdirected_op
|---
|---
if (!op_has_sufficient_caps(op)) //沒有足夠cap,則直接返回失敗
|---osd->reply_op_error(op, -eperm); return
|---
if (op->includes_pg_op()) //op is oprequest 對於請求中包含對pg的操作 ceph_osd_rmw_flag_pgod
|---
return do_pg_op(op); //void primarylogpg::do_pg_op(oprequestref op)
|---
|---物件長度,如果大於osd_max_object_name_len,則osd->reply_op_error(op, -enametoolong); return
|---物件local key長度,如果大於osd_max_object_name_len,則osd->reply_op_error(op, -enametoolong); return
|---物件local 命名空間長度,如果大於osd_max_object_name_len,則osd->reply_op_error(op, -enametoolong); return
|---
if (int r = osd->store->validate_hobject_key(head)) object的head是否有效
|---無效 osd->reply_op_error(op, r); return
|---
if (get_osdmap()->is_blacklisted(m->get_source_addr()))
|---檢查op請求的位址是否在osdmap的blacklist中,如果是osd->reply_op_error(op, -eblacklisted); return
|---bool write_ordered = op->rwordered(); //是否是寫請求
|---int64_t poolid = get_pgid().pool();
|---
if (op->may_write()) //如果是寫請求
|---const pg_pool_t *pi = get_osdmap()->get_pg_pool(poolid); //獲取對應的pool,pool獲取失敗,直接return?難道沒有返回訊息?
|---
if (m->get_snapid() != ceph_nosnap) //write to clone not valid
|---reply_op_error
|---
if (cct->_conf->osd_max_write_size && m->get_data_len() > cct->_conf->osd_max_write_size <<
20) |---寫請求的資料大於osd_max_write_size <<
20 則osd->reply_op_error(op, -eblacklisted); return
|---
if (is_unreadable_object(head)) // head 有效
|---如果不是主osd則reply_op_error
|---
if (can_backoff && (g_conf->osd_backoff_on_degraded || (g_conf->osd_backoff_on_unfound && missing_loc.is_unfound(head))))
|---條件成立:add_backoff(session, head, head); maybe_kick_recovery(head);嘗試啟動recovery
|---條件不成立:maybe_kick_recovery(head);嘗試啟動recovery
|---
return
|---
if (write_ordered && scrubber.is_chunky_scrub_active() && write_blocked_by_scrub(head))
|---waiting_for_scrub.push_back(op) 寫請求並且
|---
if (write_ordered && blocked_iter != objects_blocked_on_degraded_snap.end())
|---wait_for_degraded_object(to_wait_on, op); head在objects_blocked_on_degraded_snap 則將op放入放入waiting_for_degraded_object
|---
if (write_ordered && blocked_snap_promote_iter != objects_blocked_on_snap_promotion.end())
|---wait_for_blocked_object 檢查head是否在objects_blocked_on_snap_promotion,如果是則將op放入waiting_for_blocked_object
|---
if (write_ordered && objects_blocked_on_cache_full.count(head))
|---block_write_on_full_cache 檢查head是否在objects_blocked_on_cache_full中,如果是則將op放入waiting_for_cache_not_full
|---檢查head的snapdir是否可讀,如果不可讀則將head的snapdir放入waiting_for_unreadable_object
|---檢查head的snapdir是否處於recovery或者backfill狀態,如果是則將head的snapdir放入waiting_for_degraded_object
|---略過流程
|---
if (obc->is_blocked() &&
!m->has_flag(ceph_osd_flag_flush))
|---object context是否處於io block狀態,如果是則將請求放入wait_for_blocked_object
|---略過流程
|---execute_ctx
|---
Cockroachdb 三 副本設定
三 副本配置 cockroachdb 副本配置可分為三個等級,集群級別 資料庫級別 表級別 格式 yaml range min bytes range max bytes 預設64m gc ttlseconds 預設24h num replicas 預設3 constraints comma sep...
彈性儲存 三副本機制
編輯 阿里雲分布式檔案系統為ecs提供穩定 高效 可靠的資料隨機訪問能力。ecs使用者對虛擬磁碟的讀寫最終都會被對映為對阿里雲資料儲存平台上的檔案的讀寫。阿里雲提供乙個扁平的線性儲存空間,在內部會對線性位址進行切片,乙個分片稱為乙個chunk。對於每乙個chunk,阿里雲會複製出三個副本,並將這些副...
分布式系統原理(3) 副本控制協議
2 基本副本協議 副本控制協議指按特定的協議流程控制副本資料的讀寫行為,使得副本滿足一定的可用性和一致性要求的分布式協議。副本控制協議要具有一定的對抗異常狀態的容錯能力,從而使得具有一定的可用性,同時要能提供一定一致性級別。由cap原理可知,設計滿足強一致性,且出現任何網路異常時都可用的副本協議是不...