system.storage.RAID.cost_model module

RAID reliability and performance cost model for various RAID levels.

class system.storage.RAID.cost_model.ResilienceScenario(*values)[source]

Bases: Enum

Resilience scenarios for a storage subsystem. This is used to model the resilience of a storage subsystem against errors.

ANY_SINGLE_SUBSYSTEM_MAY_FAIL = 1
ALL_BUT_ONE_SUBSYSTEM_MAY_FAIL = 42
class system.storage.RAID.cost_model.SubSystem[source]

Bases: ABC

A cost model for an abstract subsystem used to model the performance of storage devices. This can be anything from a single chip of an SSD to a whole RAID subsystem. The subsystem has to provide information about its performance characteristics.

abstractmethod get_sequential_read_performance() → int[source]

Returns the sequential read performance of the subsystem in MB/s.

abstractmethod get_sequential_write_performance() → int[source]

Returns the sequential write performance of the subsystem in MB/s.

abstractmethod get_read_IO_performance() → int[source]

Returns the read-IOPs (random read I/O operations per second) of the subsystem. Assumes uniform distribution of read requests to the different subsystems.

abstractmethod get_write_IO_performance() → int[source]

Returns the write-IOPs (random write I/O operations per second) of the subsystem. Assumes uniform distribution of write requests to the different subsystems.

abstractmethod get_storage_blow_up() → float[source]

Returns the storage blow-up in terms of the extra storage space introduced by the subsystem. This means, if we return 1.1 this means we add 10% more storage space to the original storage space, 1.0 means no extra storage space is added.

abstractmethod get_resilience_scenario() → tuple[ResilienceScenario, Iterator[SubSystem] | None] | None[source]

Returns the scenario this SubSystem is resilient against, i.e. this scenario may happen, still this subsystem instance can recover all data.

get_resilience_scenarios(rec_depth: int = 0) → Iterator[tuple[int, SubSystem, ResilienceScenario, Iterator[SubSystem] | None]][source]

Returns an Iterator over all resilience scenarios recursively. Each tuple contains: 0. the subsystem instance, 1. the resilience scenario for that instance, and 2. an iterator over the children subsystems that may fail or None.

class system.storage.RAID.cost_model.SubSystemArray(subsystems: list[SubSystem])[source]

Bases: SubSystem, ABC

A cost model for an abstract subsystem keeping a list of references to nested subsystems.

get_resilience_scenarios(rec_depth: int = 0) → Iterator[tuple[int, SubSystem, ResilienceScenario, Iterator[SubSystem] | None]][source]

Returns an Iterator over all resilience scenarios of the subsystems in this subsystem recursively. Each tuple contains: 0. the subsystem instance, 1. the resilience scenario for that instance, and 2. an iterator over the children subsystems that may fail or None.

class system.storage.RAID.cost_model.Device(sequential_read_performance: int, sequential_write_performance: int, read_IO_performance: int, write_IO_performance: int, storage_blow_up: float = 1)[source]

Bases: SubSystem

A device in a storage subsystem. This class must provide information about its performance characteristics.

get_sequential_read_performance() → int[source]

Returns the sequential read performance of the device in MB/s.

get_sequential_write_performance() → int[source]

Returns the sequential write performance of the device in MB/s.

get_read_IO_performance() → int[source]

Returns the read-IOPs (read I/O operations per second) of the device.

get_write_IO_performance() → int[source]

Returns the write-IOPs (write I/O operations per second) of the device.

get_storage_blow_up() → float[source]

Returns the storage blow-up in terms of the extra storage space introduced by the subsystem. This means, if we return 1.1 this means we add 10% more storage space to the original storage space, 1.0 means no extra storage space is added. A value < 1.0 means we reduce the storage space, i.e. by using compression.

get_resilience_scenario() → tuple[ResilienceScenario, Iterator[SubSystem] | None] | None[source]

A device is not resilient against any failure.

class system.storage.RAID.cost_model.RAID_0(subsystems: list[SubSystem])[source]

Bases: SubSystemArray

RAID 0: Striping without parity

get_sequential_read_performance() → int[source]

Read performance is the read performance of the slowest subsystem (the minimum) times the number of subsystems, since striping reads from all subsystems in parallel.

get_sequential_write_performance() → int[source]

Write performance is the write performance of the slowest subsystem (the minimum) times the number of subsystems, since striping writes to all subsystems in parallel.

get_read_IO_performance() → int[source]

Read IOPs is the sum of all read IOPs of the subsystems. Assumes uniform distribution of read requests to the different subsystems.

get_write_IO_performance() → int[source]

Write IOPs is the sum of all write IOPs of the subsystems. Assumes uniform distribution of write requests to the different subsystems.

get_storage_blow_up() → float[source]

Returns the storage blow-up in terms of the extra storage space introduced by the subsystem. This means, if we return 1.1 this means we add 10% more storage space to the original storage space, 1.0 means no extra storage space is added. A value < 1.0 means we reduce the storage space, i.e. by using compression.

get_resilience_scenario() → tuple[ResilienceScenario, Iterator[SubSystem] | None][source]

RAID 0 is not resilient against any failure.

class system.storage.RAID.cost_model.RAID_1(subsystems: list[SubSystem])[source]

Bases: SubSystemArray

RAID 1: Mirroring

get_sequential_read_performance() → int[source]

Read performance is the sum of the read performances of all subsystems: RAID 1 mirrors the data, so every subsystem holds a full copy and can serve reads in parallel.

get_sequential_write_performance() → int[source]

Write performance is the minimum of all write performances of the subsystems, i.e. we have to wait for the slowest subsystem. No real speedup here.

get_read_IO_performance() → int[source]

Returns the sum of the read IOPs of all subsystems.

get_write_IO_performance() → int[source]

Returns the minimum of the write-IOPs of all subsystems.

get_storage_blow_up() → float[source]

Returns the storage blow-up in terms of the extra storage space introduced by the subsystem. This means, if we return 1.1 this means we add 10% more storage space to the original storage space, 1.0 means no extra storage space is added. A value < 1.0 means we reduce the storage space, i.e. by using compression.

get_resilience_scenario() → tuple[ResilienceScenario, Iterator[SubSystem] | None] | None[source]

RAID 1 is resilient against an error where all but one subsystem fails.

class system.storage.RAID.cost_model.RAID_5(subsystems: list[SubSystem])[source]

Bases: SubSystemArray

RAID 5: Striping with distributed (round-robin) parity

get_sequential_read_performance() → int[source]

Read performance is the read performance of the slowest subsystem (the minimum) times the number of subsystems minus 1 (one subsystem’s worth of throughput is spent on parity).

get_sequential_write_performance() → int[source]

Write performance is the write performance of the slowest subsystem (the minimum) times the number of subsystems minus 1 (one subsystem’s worth of throughput is spent on parity).

get_read_IO_performance() → int[source]

Read IOPs is the average read IOPs of the subsystems times (the number of subsystems minus 1).

get_write_IO_performance() → int[source]

Write IOPs is the average write IOPs of the subsystems times (the number of subsystems minus 1).

get_storage_blow_up() → float[source]

Returns the storage blow-up in terms of the extra storage space introduced by the subsystem. This means, if we return 1.1 this means we add 10% more storage space to the original storage space, 1.0 means no extra storage space is added. A value < 1.0 means we reduce the storage space, i.e. by using compression.

get_resilience_scenario() → tuple[ResilienceScenario, Iterator[SubSystem] | None] | None[source]

RAID 5 is resilient against a single subsystem failure.