garage/src/table/replication/fullcopy.rs

74 lines
2 KiB
Rust
Raw Permalink Normal View History

use std::sync::Arc;
use garage_rpc::layout::*;
2021-10-14 09:50:12 +00:00
use garage_rpc::system::System;
2020-04-24 10:10:01 +00:00
use garage_util::data::*;
2021-03-11 15:54:15 +00:00
use crate::replication::*;
// TODO: find a way to track layout changes for this as well
// The hard thing is that this data is stored also on gateway nodes,
// whereas sharded data is stored only on non-Gateway nodes (storage nodes)
// Also we want to be more tolerant to failures of gateways so we don't
// want to do too much holding back of data when progress of gateway
// nodes is not reported in the layout history's ack/sync/sync_ack maps.
2021-03-26 18:41:46 +00:00
/// Full replication schema: all nodes store everything
/// Advantage: do all reads locally, extremely fast
/// Inconvenient: only suitable to reasonably small tables
/// Inconvenient: if some writes fail, nodes will read outdated data
#[derive(Clone)]
pub struct TableFullReplication {
2021-03-26 18:41:46 +00:00
/// The membership manager of this node
2021-03-16 10:14:27 +00:00
pub system: Arc<System>,
}
impl TableReplication for TableFullReplication {
2023-11-15 14:40:44 +00:00
type WriteSets = Vec<Vec<Uuid>>;
2023-11-14 13:28:16 +00:00
fn storage_nodes(&self, _hash: &Hash) -> Vec<Uuid> {
let layout = self.system.cluster_layout();
layout.current().all_nodes().to_vec()
}
fn read_nodes(&self, _hash: &Hash) -> Vec<Uuid> {
2021-03-16 10:14:27 +00:00
vec![self.system.id]
}
fn read_quorum(&self) -> usize {
1
}
2023-11-15 14:40:44 +00:00
fn write_sets(&self, hash: &Hash) -> Self::WriteSets {
2023-11-14 13:28:16 +00:00
vec![self.storage_nodes(hash)]
}
2021-03-16 10:14:27 +00:00
fn write_quorum(&self) -> usize {
2023-11-14 12:06:16 +00:00
let nmembers = self.system.cluster_layout().current().all_nodes().len();
let max_faults = if nmembers > 1 { 1 } else { 0 };
if nmembers > max_faults {
nmembers - max_faults
} else {
1
}
}
2021-03-16 11:18:03 +00:00
fn partition_of(&self, _hash: &Hash) -> Partition {
0u16
}
fn sync_partitions(&self) -> SyncPartitions {
let layout = self.system.cluster_layout();
let layout_version = layout.current().version;
SyncPartitions {
layout_version,
partitions: vec![SyncPartition {
partition: 0u16,
first_hash: [0u8; 32].into(),
last_hash: [0xff; 32].into(),
storage_sets: vec![layout.current().all_nodes().to_vec()],
}],
}
}
}