@@ -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_,
@@ -23,6 +24,9 @@ StorageObjectStorageStableTaskDistributor::StorageObjectStorageStableTaskDistrib
2324 , lock_object_storage_task_distribution_us(lock_object_storage_task_distribution_ms_ * 1000 )
2425 , iterator_exhausted(false )
2526{
27+ size_t nodes = ids_of_nodes.size ();
28+ for (size_t i = 0 ; i < nodes; ++i)
29+ replica_to_files_to_be_processed[i] = std::list<ObjectInfoPtr>{};
2630}
2731
2832ObjectInfoPtr StorageObjectStorageStableTaskDistributor::getNextTask (size_t number_of_current_replica)
@@ -31,16 +35,27 @@ ObjectInfoPtr StorageObjectStorageStableTaskDistributor::getNextTask(size_t numb
3135
3236 saveLastNodeActivity (number_of_current_replica);
3337
34- // 1. Check pre-queued files first
35- if (auto file = getPreQueuedFile (number_of_current_replica))
36- return file;
38+ auto processed_file_list_ptr = replica_to_files_to_be_processed.find (number_of_current_replica);
39+ if (processed_file_list_ptr == replica_to_files_to_be_processed.end ())
40+ throw Exception (
41+ ErrorCodes::LOGICAL_ERROR,
42+ " Replica number {} was marked as lost, can't set task for it anymore" ,
43+ number_of_current_replica
44+ );
3745
46+ // 1. Check pre-queued files first
47+ auto file = getPreQueuedFile (number_of_current_replica);
3848 // 2. Try to find a matching file from the iterator
39- if (auto file = getMatchingFileFromIterator (number_of_current_replica))
40- return file;
41-
49+ if (!file)
50+ file = getMatchingFileFromIterator (number_of_current_replica);
4251 // 3. Process unprocessed files if iterator is exhausted
43- return getAnyUnprocessedFile (number_of_current_replica);
52+ if (!file)
53+ file = getAnyUnprocessedFile (number_of_current_replica);
54+
55+ if (file)
56+ processed_file_list_ptr->second .push_back (file);
57+
58+ return file;
4459}
4560
4661size_t StorageObjectStorageStableTaskDistributor::getReplicaForFile (const String & file_path)
@@ -52,16 +67,27 @@ size_t StorageObjectStorageStableTaskDistributor::getReplicaForFile(const String
5267 return 0 ;
5368
5469 // / Rendezvous hashing
55- size_t best_id = 0 ;
56- UInt64 best_weight = sipHash64 (ids_of_nodes[0 ] + file_path);
57- for (size_t id = 1 ; id < nodes_count; ++id)
70+ auto replica = replica_to_files_to_be_processed.begin ();
71+ if (replica == replica_to_files_to_be_processed.end ())
72+ throw Exception (
73+ ErrorCodes::LOGICAL_ERROR,
74+ " No active replicas, can't find best replica for file {}" ,
75+ file_path
76+ );
77+
78+ size_t best_id = replica->first ;
79+ UInt64 best_weight = sipHash64 (ids_of_nodes[best_id] + file_path);
80+ ++replica;
81+ while (replica != replica_to_files_to_be_processed.end ())
5882 {
83+ size_t id = replica->first ;
5984 UInt64 weight = sipHash64 (ids_of_nodes[id] + file_path);
6085 if (weight > best_weight)
6186 {
6287 best_weight = weight;
6388 best_id = id;
6489 }
90+ ++replica;
6591 }
6692 return best_id;
6793}
@@ -234,4 +260,28 @@ void StorageObjectStorageStableTaskDistributor::saveLastNodeActivity(size_t numb
234260 last_node_activity[number_of_current_replica] = now;
235261}
236262
263+ void StorageObjectStorageStableTaskDistributor::rescheduleTasksFromReplica (size_t number_of_current_replica)
264+ {
265+ LOG_INFO (log, " Replica {} is marked as lost, tasks are returned to queue" , number_of_current_replica);
266+ std::lock_guard lock (mutex);
267+
268+ auto processed_file_list_ptr = replica_to_files_to_be_processed.find (number_of_current_replica);
269+ if (processed_file_list_ptr == replica_to_files_to_be_processed.end ())
270+ throw Exception (
271+ ErrorCodes::LOGICAL_ERROR,
272+ " Replica number {} was marked as lost already" ,
273+ number_of_current_replica
274+ );
275+
276+ if (replica_to_files_to_be_processed.size () < 2 )
277+ throw Exception (
278+ ErrorCodes::CANNOT_READ_ALL_DATA,
279+ " All replicas were marked as lost"
280+ );
281+
282+ replica_to_files_to_be_processed.erase (number_of_current_replica);
283+ for (const auto & file : processed_file_list_ptr->second )
284+ unprocessed_files.emplace (file->getPath (), std::make_pair (file, getReplicaForFile (file->getPath ())));
285+ }
286+
237287}
0 commit comments