@@ -9,7 +9,8 @@ namespace DB
99namespace ErrorCodes
1010{
1111 extern const int LOGICAL_ERROR;
12- }
12+ extern const int CANNOT_READ_ALL_DATA;
13+ };
1314
1415StorageObjectStorageStableTaskDistributor::StorageObjectStorageStableTaskDistributor (
1516 std::shared_ptr<IObjectIterator> iterator_,
@@ -21,6 +22,9 @@ StorageObjectStorageStableTaskDistributor::StorageObjectStorageStableTaskDistrib
2122 , lock_object_storage_task_distribution_us(lock_object_storage_task_distribution_ms_ * 1000 )
2223 , iterator_exhausted(false )
2324{
25+ size_t nodes = ids_of_nodes.size ();
26+ for (size_t i = 0 ; i < nodes; ++i)
27+ replica_to_files_to_be_processed[i] = std::list<String>{};
2428}
2529
2630std::optional<String> StorageObjectStorageStableTaskDistributor::getNextTask (size_t number_of_current_replica)
@@ -36,16 +40,27 @@ std::optional<String> StorageObjectStorageStableTaskDistributor::getNextTask(siz
3640
3741 saveLastNodeActivity (number_of_current_replica);
3842
39- // 1. Check pre-queued files first
40- if (auto file = getPreQueuedFile (number_of_current_replica))
41- return file;
43+ auto processed_file_list_ptr = replica_to_files_to_be_processed.find (number_of_current_replica);
44+ if (processed_file_list_ptr == replica_to_files_to_be_processed.end ())
45+ throw Exception (
46+ ErrorCodes::LOGICAL_ERROR,
47+ " Replica number {} was marked as lost, can't set task for it anymore" ,
48+ number_of_current_replica
49+ );
4250
51+ // 1. Check pre-queued files first
52+ std::optional<String> file = getPreQueuedFile (number_of_current_replica);
4353 // 2. Try to find a matching file from the iterator
44- if (auto file = getMatchingFileFromIterator (number_of_current_replica))
45- return file;
46-
54+ if (!file.has_value ())
55+ file = getMatchingFileFromIterator (number_of_current_replica);
4756 // 3. Process unprocessed files if iterator is exhausted
48- return getAnyUnprocessedFile (number_of_current_replica);
57+ if (!file.has_value ())
58+ file = getAnyUnprocessedFile (number_of_current_replica);
59+
60+ if (file.has_value ())
61+ processed_file_list_ptr->second .push_back (*file);
62+
63+ return file;
4964}
5065
5166size_t StorageObjectStorageStableTaskDistributor::getReplicaForFile (const String & file_path)
@@ -57,16 +72,27 @@ size_t StorageObjectStorageStableTaskDistributor::getReplicaForFile(const String
5772 return 0 ;
5873
5974 // / Rendezvous hashing
60- size_t best_id = 0 ;
61- UInt64 best_weight = sipHash64 (ids_of_nodes[0 ] + file_path);
62- for (size_t id = 1 ; id < nodes_count; ++id)
75+ auto replica = replica_to_files_to_be_processed.begin ();
76+ if (replica == replica_to_files_to_be_processed.end ())
77+ throw Exception (
78+ ErrorCodes::LOGICAL_ERROR,
79+ " No active replicas, can't find best replica for file {}" ,
80+ file_path
81+ );
82+
83+ size_t best_id = replica->first ;
84+ UInt64 best_weight = sipHash64 (ids_of_nodes[best_id] + file_path);
85+ ++replica;
86+ while (replica != replica_to_files_to_be_processed.end ())
6387 {
88+ size_t id = replica->first ;
6489 UInt64 weight = sipHash64 (ids_of_nodes[id] + file_path);
6590 if (weight > best_weight)
6691 {
6792 best_weight = weight;
6893 best_id = id;
6994 }
95+ ++replica;
7096 }
7197 return best_id;
7298}
@@ -230,4 +256,28 @@ void StorageObjectStorageStableTaskDistributor::saveLastNodeActivity(size_t numb
230256 last_node_activity[number_of_current_replica] = now;
231257}
232258
259+ void StorageObjectStorageStableTaskDistributor::rescheduleTasksFromReplica (size_t number_of_current_replica)
260+ {
261+ LOG_INFO (log, " Replica {} is marked as lost, tasks are returned to queue" , number_of_current_replica);
262+ std::lock_guard lock (mutex);
263+
264+ auto processed_file_list_ptr = replica_to_files_to_be_processed.find (number_of_current_replica);
265+ if (processed_file_list_ptr == replica_to_files_to_be_processed.end ())
266+ throw Exception (
267+ ErrorCodes::LOGICAL_ERROR,
268+ " Replica number {} was marked as lost already" ,
269+ number_of_current_replica
270+ );
271+
272+ if (replica_to_files_to_be_processed.size () < 2 )
273+ throw Exception (
274+ ErrorCodes::CANNOT_READ_ALL_DATA,
275+ " All replicas were marked as lost"
276+ );
277+
278+ replica_to_files_to_be_processed.erase (number_of_current_replica);
279+ for (const auto & file_path : processed_file_list_ptr->second )
280+ unprocessed_files[file_path] = getReplicaForFile (file_path);
281+ }
282+
233283}
0 commit comments