Add EIO retry timeout and allow to disable these retries, rename up_wait_retry_interval to client_retry_interval
Test / buildenv (push) Successful in 13s
Details
Test / build (push) Successful in 2m36s
Details
Test / test_cas (push) Successful in 11s
Details
Test / make_test (push) Successful in 37s
Details
Test / test_change_pg_count (push) Successful in 38s
Details
Test / test_change_pg_size (push) Successful in 9s
Details
Test / test_change_pg_count_ec (push) Successful in 34s
Details
Test / test_create_nomaxid (push) Successful in 9s
Details
Test / test_etcd_fail (push) Successful in 1m33s
Details
Test / test_interrupted_rebalance_imm (push) Successful in 1m34s
Details
Test / test_add_osd (push) Successful in 2m29s
Details
Test / test_failure_domain (push) Successful in 50s
Details
Test / test_interrupted_rebalance (push) Successful in 2m50s
Details
Test / test_snapshot (push) Successful in 33s
Details
Test / test_interrupted_rebalance_ec_imm (push) Successful in 1m39s
Details
Test / test_snapshot_ec (push) Successful in 27s
Details
Test / test_minsize_1 (push) Successful in 14s
Details
Test / test_rm (push) Successful in 18s
Details
Test / test_interrupted_rebalance_ec (push) Successful in 2m6s
Details
Test / test_move_reappear (push) Successful in 23s
Details
Test / test_snapshot_down (push) Successful in 30s
Details
Test / test_snapshot_down_ec (push) Successful in 29s
Details
Test / test_splitbrain (push) Successful in 26s
Details
Test / test_snapshot_chain (push) Successful in 1m48s
Details
Test / test_snapshot_chain_ec (push) Successful in 2m2s
Details
Test / test_switch_primary (push) Successful in 36s
Details
Test / test_write_no_same (push) Successful in 24s
Details
Test / test_write (push) Successful in 1m11s
Details
Test / test_write_xor (push) Successful in 1m49s
Details
Test / test_heal_csum_32k_dmj (push) Failing after 10m18s
Details
Test / test_heal_csum_32k_dj (push) Failing after 10m21s
Details
Test / test_heal_csum_32k (push) Failing after 10m13s
Details
Test / test_scrub (push) Successful in 30s
Details
Test / test_heal_csum_4k_dmj (push) Failing after 10m14s
Details
Test / test_scrub_zero_osd_2 (push) Successful in 28s
Details
Test / test_scrub_xor (push) Successful in 27s
Details
Test / test_heal_csum_4k_dj (push) Failing after 10m18s
Details
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 36s
Details
Test / test_scrub_pg_size_3 (push) Successful in 46s
Details
Test / test_scrub_ec (push) Successful in 27s
Details
Test / test_heal_csum_4k (push) Failing after 10m14s
Details
Test / test_rebalance_verify_imm (push) Successful in 2m0s
Details
Test / test_rebalance_verify (push) Failing after 6m7s
Details
Test / test_rebalance_verify_ec (push) Failing after 6m44s
Details
Test / test_rebalance_verify_ec_imm (push) Failing after 6m57s
Details
Test / test_heal_pg_size_2 (push) Failing after 10m9s
Details
Test / test_heal_ec (push) Failing after 10m11s
Details
Test / buildenv (push) Successful in 13s
Details
Test / build (push) Successful in 2m36s
Details
Test / test_cas (push) Successful in 11s
Details
Test / make_test (push) Successful in 37s
Details
Test / test_change_pg_count (push) Successful in 38s
Details
Test / test_change_pg_size (push) Successful in 9s
Details
Test / test_change_pg_count_ec (push) Successful in 34s
Details
Test / test_create_nomaxid (push) Successful in 9s
Details
Test / test_etcd_fail (push) Successful in 1m33s
Details
Test / test_interrupted_rebalance_imm (push) Successful in 1m34s
Details
Test / test_add_osd (push) Successful in 2m29s
Details
Test / test_failure_domain (push) Successful in 50s
Details
Test / test_interrupted_rebalance (push) Successful in 2m50s
Details
Test / test_snapshot (push) Successful in 33s
Details
Test / test_interrupted_rebalance_ec_imm (push) Successful in 1m39s
Details
Test / test_snapshot_ec (push) Successful in 27s
Details
Test / test_minsize_1 (push) Successful in 14s
Details
Test / test_rm (push) Successful in 18s
Details
Test / test_interrupted_rebalance_ec (push) Successful in 2m6s
Details
Test / test_move_reappear (push) Successful in 23s
Details
Test / test_snapshot_down (push) Successful in 30s
Details
Test / test_snapshot_down_ec (push) Successful in 29s
Details
Test / test_splitbrain (push) Successful in 26s
Details
Test / test_snapshot_chain (push) Successful in 1m48s
Details
Test / test_snapshot_chain_ec (push) Successful in 2m2s
Details
Test / test_switch_primary (push) Successful in 36s
Details
Test / test_write_no_same (push) Successful in 24s
Details
Test / test_write (push) Successful in 1m11s
Details
Test / test_write_xor (push) Successful in 1m49s
Details
Test / test_heal_csum_32k_dmj (push) Failing after 10m18s
Details
Test / test_heal_csum_32k_dj (push) Failing after 10m21s
Details
Test / test_heal_csum_32k (push) Failing after 10m13s
Details
Test / test_scrub (push) Successful in 30s
Details
Test / test_heal_csum_4k_dmj (push) Failing after 10m14s
Details
Test / test_scrub_zero_osd_2 (push) Successful in 28s
Details
Test / test_scrub_xor (push) Successful in 27s
Details
Test / test_heal_csum_4k_dj (push) Failing after 10m18s
Details
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 36s
Details
Test / test_scrub_pg_size_3 (push) Successful in 46s
Details
Test / test_scrub_ec (push) Successful in 27s
Details
Test / test_heal_csum_4k (push) Failing after 10m14s
Details
Test / test_rebalance_verify_imm (push) Successful in 2m0s
Details
Test / test_rebalance_verify (push) Failing after 6m7s
Details
Test / test_rebalance_verify_ec (push) Failing after 6m44s
Details
Test / test_rebalance_verify_ec_imm (push) Failing after 6m57s
Details
Test / test_heal_pg_size_2 (push) Failing after 10m9s
Details
Test / test_heal_ec (push) Failing after 10m11s
Details
parent
fc413038d1
commit
3e26664da2
|
@ -1,3 +1,27 @@
|
|||
- name: client_retry_interval
|
||||
type: ms
|
||||
min: 10
|
||||
default: 50
|
||||
online: true
|
||||
info: |
|
||||
Retry time for I/O requests failed due to inactive PGs or network
|
||||
connectivity errors.
|
||||
info_ru: |
|
||||
Время повтора запросов ввода-вывода, неудачных из-за неактивных PG или
|
||||
ошибок сети.
|
||||
- name: client_eio_retry_interval
|
||||
type: ms
|
||||
default: 1000
|
||||
online: true
|
||||
info: |
|
||||
Retry time for I/O requests failed due to data corruption or unfinished
|
||||
EC object deletions (has_incomplete PG state). 0 disables such retries
|
||||
and clients are not blocked and just get EIO error code instead.
|
||||
info_ru: |
|
||||
Время повтора запросов ввода-вывода, неудачных из-за повреждения данных
|
||||
или незавершённых удалений EC-объектов (состояния PG has_incomplete).
|
||||
0 отключает повторы таких запросов и клиенты не блокируются, а вместо
|
||||
этого просто получают код ошибки EIO.
|
||||
- name: client_max_dirty_bytes
|
||||
type: int
|
||||
default: 33554432
|
||||
|
|
|
@ -243,21 +243,6 @@
|
|||
Максимальное время ожидания ответа на запрос проверки состояния соединения.
|
||||
Если OSD не отвечает за это время, соединение отключается и производится
|
||||
повторная попытка соединения.
|
||||
- name: up_wait_retry_interval
|
||||
type: ms
|
||||
min: 10
|
||||
default: 50
|
||||
online: true
|
||||
info: |
|
||||
OSDs respond to clients with a special error code when they receive I/O
|
||||
requests for a PG that's not synchronized and started. This parameter sets
|
||||
the time for the clients to wait before re-attempting such I/O requests.
|
||||
info_ru: |
|
||||
Когда OSD получают от клиентов запросы ввода-вывода, относящиеся к не
|
||||
поднятым на данный момент на них PG, либо к PG в процессе синхронизации,
|
||||
они отвечают клиентам специальным кодом ошибки, означающим, что клиент
|
||||
должен некоторое время подождать перед повторением запроса. Именно это время
|
||||
ожидания задаёт данный параметр.
|
||||
- name: max_etcd_attempts
|
||||
type: int
|
||||
default: 5
|
||||
|
|
|
@ -86,13 +86,14 @@ const etcd_tree = {
|
|||
client_max_buffered_bytes: 33554432,
|
||||
client_max_buffered_ops: 1024,
|
||||
client_max_writeback_iodepth: 256,
|
||||
client_retry_interval: 50, // ms. min: 10
|
||||
client_eio_retry_interval: 1000, // ms
|
||||
// client and osd - configurable online
|
||||
log_level: 0,
|
||||
peer_connect_interval: 5, // seconds. min: 1
|
||||
peer_connect_timeout: 5, // seconds. min: 1
|
||||
osd_idle_timeout: 5, // seconds. min: 1
|
||||
osd_ping_timeout: 5, // seconds. min: 1
|
||||
up_wait_retry_interval: 50, // ms. min: 10
|
||||
max_etcd_attempts: 5,
|
||||
etcd_quick_timeout: 1000, // ms
|
||||
etcd_slow_timeout: 5000, // ms
|
||||
|
|
|
@ -265,7 +265,7 @@ void cluster_client_t::erase_op(cluster_op_t *op)
|
|||
}
|
||||
}
|
||||
|
||||
void cluster_client_t::continue_ops(bool up_retry)
|
||||
void cluster_client_t::continue_ops(int time_passed)
|
||||
{
|
||||
if (!pgs_loaded)
|
||||
{
|
||||
|
@ -277,22 +277,27 @@ void cluster_client_t::continue_ops(bool up_retry)
|
|||
// Attempt to reenter the function
|
||||
return;
|
||||
}
|
||||
int reset_duration = retry_timeout_duration;
|
||||
restart:
|
||||
continuing_ops = 1;
|
||||
for (auto op = op_queue_head; op; )
|
||||
{
|
||||
cluster_op_t *next_op = op->next;
|
||||
if (!op->up_wait || up_retry)
|
||||
if (op->retry_after && time_passed)
|
||||
{
|
||||
op->up_wait = false;
|
||||
if (!op->prev_wait)
|
||||
op->retry_after = op->retry_after > time_passed ? op->retry_after-time_passed : 0;
|
||||
if (op->retry_after && (!reset_duration || op->retry_after < reset_duration))
|
||||
{
|
||||
if (op->opcode == OSD_OP_SYNC)
|
||||
continue_sync(op);
|
||||
else
|
||||
continue_rw(op);
|
||||
reset_duration = op->retry_after;
|
||||
}
|
||||
}
|
||||
if (!op->retry_after && !op->prev_wait)
|
||||
{
|
||||
if (op->opcode == OSD_OP_SYNC)
|
||||
continue_sync(op);
|
||||
else
|
||||
continue_rw(op);
|
||||
}
|
||||
op = next_op;
|
||||
if (continuing_ops == 2)
|
||||
{
|
||||
|
@ -300,6 +305,29 @@ restart:
|
|||
}
|
||||
}
|
||||
continuing_ops = 0;
|
||||
if (reset_duration)
|
||||
{
|
||||
reset_retry_timer(reset_duration);
|
||||
}
|
||||
}
|
||||
|
||||
void cluster_client_t::reset_retry_timer(int new_duration)
|
||||
{
|
||||
if (retry_timeout_duration && retry_timeout_duration <= new_duration || !new_duration)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (retry_timeout_id)
|
||||
{
|
||||
tfd->clear_timer(retry_timeout_id);
|
||||
}
|
||||
retry_timeout_duration = new_duration;
|
||||
retry_timeout_id = tfd->set_timer(retry_timeout_duration, false, [this](int)
|
||||
{
|
||||
retry_timeout_id = 0;
|
||||
retry_timeout_duration = 0;
|
||||
continue_ops(retry_timeout_duration);
|
||||
});
|
||||
}
|
||||
|
||||
void cluster_client_t::on_load_config_hook(json11::Json::object & etcd_global_config)
|
||||
|
@ -349,15 +377,25 @@ void cluster_client_t::on_load_config_hook(json11::Json::object & etcd_global_co
|
|||
{
|
||||
client_max_writeback_iodepth = DEFAULT_CLIENT_MAX_WRITEBACK_IODEPTH;
|
||||
}
|
||||
// up_wait_retry_interval
|
||||
up_wait_retry_interval = config["up_wait_retry_interval"].uint64_value();
|
||||
if (!up_wait_retry_interval)
|
||||
// client_retry_interval
|
||||
client_retry_interval = config["client_retry_interval"].uint64_value();
|
||||
if (!client_retry_interval)
|
||||
{
|
||||
up_wait_retry_interval = 50;
|
||||
client_retry_interval = 50;
|
||||
}
|
||||
else if (up_wait_retry_interval < 10)
|
||||
else if (client_retry_interval < 10)
|
||||
{
|
||||
up_wait_retry_interval = 10;
|
||||
client_retry_interval = 10;
|
||||
}
|
||||
// client_eio_retry_interval
|
||||
client_eio_retry_interval = 1000;
|
||||
if (!config["client_eio_retry_interval"].is_null())
|
||||
{
|
||||
client_eio_retry_interval = config["client_eio_retry_interval"].uint64_value();
|
||||
if (client_eio_retry_interval && client_eio_retry_interval < 10)
|
||||
{
|
||||
client_eio_retry_interval = 10;
|
||||
}
|
||||
}
|
||||
// log_level
|
||||
log_level = config["log_level"].uint64_value();
|
||||
|
@ -716,15 +754,8 @@ resume_1:
|
|||
// We'll need to retry again
|
||||
if (op->parts[i].flags & PART_RETRY)
|
||||
{
|
||||
op->up_wait = true;
|
||||
if (!retry_timeout_id)
|
||||
{
|
||||
retry_timeout_id = tfd->set_timer(up_wait_retry_interval, false, [this](int)
|
||||
{
|
||||
retry_timeout_id = 0;
|
||||
continue_ops(true);
|
||||
});
|
||||
}
|
||||
op->retry_after = client_retry_interval;
|
||||
reset_retry_timer(client_retry_interval);
|
||||
}
|
||||
op->state = 1;
|
||||
}
|
||||
|
@ -780,10 +811,9 @@ resume_2:
|
|||
return 1;
|
||||
}
|
||||
else if (op->retval != 0 && !(op->flags & OP_FLUSH_BUFFER) &&
|
||||
op->retval != -EPIPE && op->retval != -EIO && op->retval != -ENOSPC)
|
||||
op->retval != -EPIPE && (op->retval != -EIO || !client_eio_retry_interval) && op->retval != -ENOSPC)
|
||||
{
|
||||
// Fatal error (neither -EPIPE, -EIO nor -ENOSPC)
|
||||
// FIXME: Add a parameter to allow to not wait for EIOs (incomplete or corrupted objects) to heal
|
||||
erase_op(op);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1171,16 +1201,12 @@ void cluster_client_t::handle_op_part(cluster_op_part_t *part)
|
|||
// All next things like timer, continue_sync/rw and stop_client may affect the operation again
|
||||
// So do all these things after modifying operation state, otherwise we may hit reenterability bugs
|
||||
// FIXME postpone such things to set_immediate here to avoid bugs
|
||||
// Mark op->up_wait = true to retry operation after a short pause (not immediately)
|
||||
op->up_wait = true;
|
||||
if (!retry_timeout_id)
|
||||
// Set op->retry_after to retry operation after a short pause (not immediately)
|
||||
if (!op->retry_after)
|
||||
{
|
||||
retry_timeout_id = tfd->set_timer(up_wait_retry_interval, false, [this](int)
|
||||
{
|
||||
retry_timeout_id = 0;
|
||||
continue_ops(true);
|
||||
});
|
||||
op->retry_after = op->retval == -EIO ? client_eio_retry_interval : client_retry_interval;
|
||||
}
|
||||
reset_retry_timer(op->retry_after);
|
||||
if (op->inflight_count == 0)
|
||||
{
|
||||
if (op->opcode == OSD_OP_SYNC)
|
||||
|
|
|
@ -59,7 +59,7 @@ protected:
|
|||
void *buf = NULL;
|
||||
cluster_op_t *orig_op = NULL;
|
||||
bool needs_reslice = false;
|
||||
bool up_wait = false;
|
||||
int retry_after = 0;
|
||||
int inflight_count = 0, done_count = 0;
|
||||
std::vector<cluster_op_part_t> parts;
|
||||
void *part_bitmaps = NULL;
|
||||
|
@ -92,9 +92,11 @@ class cluster_client_t
|
|||
uint64_t client_max_writeback_iodepth = 0;
|
||||
|
||||
int log_level = 0;
|
||||
int up_wait_retry_interval = 500; // ms
|
||||
int client_retry_interval = 50; // ms
|
||||
int client_eio_retry_interval = 1000; // ms
|
||||
|
||||
int retry_timeout_id = 0;
|
||||
int retry_timeout_duration = 0;
|
||||
std::vector<cluster_op_t*> offline_ops;
|
||||
cluster_op_t *op_queue_head = NULL, *op_queue_tail = NULL;
|
||||
writeback_cache_t *wb = NULL;
|
||||
|
@ -131,7 +133,7 @@ public:
|
|||
|
||||
bool get_immediate_commit(uint64_t inode);
|
||||
|
||||
void continue_ops(bool up_retry = false);
|
||||
void continue_ops(int time_passed = 0);
|
||||
inode_list_t *list_inode_start(inode_t inode,
|
||||
std::function<void(inode_list_t* lst, std::set<object_id>&& objects, pg_num_t pg_num, osd_num_t primary_osd, int status)> callback);
|
||||
int list_pg_count(inode_list_t *lst);
|
||||
|
@ -152,6 +154,7 @@ protected:
|
|||
int continue_rw(cluster_op_t *op);
|
||||
bool check_rw(cluster_op_t *op);
|
||||
void slice_rw(cluster_op_t *op);
|
||||
void reset_retry_timer(int new_duration);
|
||||
bool try_send(cluster_op_t *op, int i);
|
||||
int continue_sync(cluster_op_t *op);
|
||||
void send_sync(cluster_op_t *op, cluster_op_part_t *part);
|
||||
|
|
Loading…
Reference in New Issue