197 lines
6 KiB
Python
197 lines
6 KiB
Python
## Quorum Systems
|
|
from quoracle import *
|
|
|
|
a = Node('a')
|
|
b = Node('b')
|
|
c = Node('c')
|
|
d = Node('d')
|
|
e = Node('e')
|
|
f = Node('f')
|
|
|
|
grid = QuorumSystem(reads=a*b*c + d*e*f)
|
|
|
|
for r in grid.read_quorums():
|
|
print(r)
|
|
|
|
for w in grid.write_quorums():
|
|
print(w)
|
|
|
|
QuorumSystem(writes=(a + b + c) * (d + e + f))
|
|
|
|
QuorumSystem(reads=a*b*c + d*e*f, writes=(a + b + c) * (d + e + f))
|
|
|
|
# QuorumSystem(reads=a+b+c, writes=d+e+f)
|
|
# ValueError: Not all read quorums intersect all write quorums
|
|
|
|
print(grid.is_read_quorum({'a', 'b', 'c'})) # True
|
|
print(grid.is_read_quorum({'a', 'b', 'c', 'd'})) # True
|
|
print(grid.is_read_quorum({'a', 'b', 'd'})) # False
|
|
|
|
print(grid.is_write_quorum({'a', 'd'})) # True
|
|
print(grid.is_write_quorum({'a', 'd', 'd'})) # True
|
|
print(grid.is_write_quorum({'a', 'b'})) # False
|
|
|
|
## Resilience
|
|
print(grid.read_resilience()) # 1
|
|
print(grid.write_resilience()) # 2
|
|
print(grid.resilience()) # 1
|
|
|
|
## Strategies
|
|
# The read quorum strategy.
|
|
sigma_r = {
|
|
frozenset({'a', 'b', 'c'}): 2.,
|
|
frozenset({'d', 'e', 'f'}): 1.,
|
|
}
|
|
|
|
# The write quorum strategy.
|
|
sigma_w = {
|
|
frozenset({'a', 'd'}): 1.,
|
|
frozenset({'b', 'e'}): 1.,
|
|
frozenset({'c', 'f'}): 1.,
|
|
}
|
|
strategy = grid.make_strategy(sigma_r, sigma_w)
|
|
|
|
print(strategy.get_read_quorum())
|
|
print(strategy.get_read_quorum())
|
|
print(strategy.get_read_quorum())
|
|
print(strategy.get_read_quorum())
|
|
print(strategy.get_write_quorum())
|
|
print(strategy.get_write_quorum())
|
|
print(strategy.get_write_quorum())
|
|
print(strategy.get_write_quorum())
|
|
|
|
## Load and Capacity
|
|
print(strategy.load(read_fraction=1)) # 2/3
|
|
|
|
print(strategy.load(write_fraction=1)) # 1/3
|
|
|
|
print(strategy.load(read_fraction=0.25)) # 5/12
|
|
|
|
print(strategy.node_load(a, read_fraction=0.25)) # 5/12
|
|
print(strategy.node_load(b, read_fraction=0.25)) # 5/12
|
|
print(strategy.node_load(c, read_fraction=0.25)) # 5/12
|
|
print(strategy.node_load(d, read_fraction=0.25)) # 1/3
|
|
print(strategy.node_load(e, read_fraction=0.25)) # 1/3
|
|
print(strategy.node_load(f, read_fraction=0.25)) # 1/3
|
|
|
|
strategy = grid.strategy(read_fraction=0.25)
|
|
print(strategy)
|
|
print(strategy.load(read_fraction=0.25)) # 3/8
|
|
|
|
print(strategy.load(read_fraction=0)) # 1/3
|
|
print(strategy.load(read_fraction=0.5)) # 5/12
|
|
print(strategy.load(read_fraction=1)) # 1/2
|
|
|
|
print(grid.load(read_fraction=0.25)) # 3/8
|
|
|
|
print(grid.capacity(read_fraction=0.25)) # 8/3
|
|
|
|
## Workload Distributions
|
|
distribution = {0.1: 0.5, 0.75: 0.5}
|
|
strategy = grid.strategy(read_fraction=distribution)
|
|
print(strategy.load(read_fraction=distribution)) # 0.404
|
|
|
|
## Heterogeneous Node
|
|
a = Node('a', capacity=1000)
|
|
b = Node('b', capacity=500)
|
|
c = Node('c', capacity=1000)
|
|
d = Node('d', capacity=500)
|
|
e = Node('e', capacity=1000)
|
|
f = Node('f', capacity=500)
|
|
|
|
grid = QuorumSystem(reads=a*b*c + d*e*f)
|
|
strategy = grid.strategy(read_fraction=0.75)
|
|
print(strategy.load(read_fraction=0.75)) # 0.00075
|
|
print(strategy.capacity(read_fraction=0.75)) # 1333
|
|
|
|
a = Node('a', write_capacity=1000, read_capacity=10000)
|
|
b = Node('b', write_capacity=500, read_capacity=5000)
|
|
c = Node('c', write_capacity=1000, read_capacity=10000)
|
|
d = Node('d', write_capacity=500, read_capacity=5000)
|
|
e = Node('e', write_capacity=1000, read_capacity=10000)
|
|
f = Node('f', write_capacity=500, read_capacity=5000)
|
|
|
|
grid = QuorumSystem(reads=a*b*c + d*e*f)
|
|
print(grid.capacity(read_fraction=1)) # 10,000
|
|
print(grid.capacity(read_fraction=0.5)) # 3913
|
|
print(grid.capacity(read_fraction=0)) # 2000
|
|
|
|
## f-resilient Strategies
|
|
strategy = grid.strategy(read_fraction=0.5, f=1)
|
|
|
|
print(strategy.get_read_quorum())
|
|
print(strategy.get_write_quorum())
|
|
|
|
print(grid.capacity(write_fraction=1, f=0))
|
|
print(grid.capacity(write_fraction=1, f=1))
|
|
|
|
write2 = QuorumSystem(writes=choose(2, [a, b, c, d, e]))
|
|
print(write2.capacity(write_fraction=1, f=0))
|
|
print(write2.capacity(write_fraction=1, f=1))
|
|
|
|
## Latency
|
|
import datetime
|
|
|
|
def seconds(x: int) -> datetime.timedelta:
|
|
return datetime.timedelta(seconds=x)
|
|
|
|
a = Node('a', write_capacity=1000, read_capacity=10000, latency=seconds(1))
|
|
b = Node('b', write_capacity=500, read_capacity=5000, latency=seconds(2))
|
|
c = Node('c', write_capacity=1000, read_capacity=10000, latency=seconds(3))
|
|
d = Node('d', write_capacity=500, read_capacity=5000, latency=seconds(4))
|
|
e = Node('e', write_capacity=1000, read_capacity=10000, latency=seconds(5))
|
|
f = Node('f', write_capacity=500, read_capacity=5000, latency=seconds(6))
|
|
grid = QuorumSystem(reads=a*b*c + d*e*f)
|
|
|
|
sigma = grid.strategy(read_fraction=0.5, optimize='latency')
|
|
print(sigma)
|
|
|
|
print(sigma.latency(read_fraction=1))
|
|
print(sigma.latency(read_fraction=0))
|
|
print(sigma.latency(read_fraction=0.5))
|
|
|
|
print(grid.latency(read_fraction=0.5, optimize='latency'))
|
|
|
|
sigma = grid.strategy(read_fraction=0.5,
|
|
optimize='latency',
|
|
load_limit=1/1500)
|
|
print(sigma)
|
|
print(sigma.capacity(read_fraction=0.5))
|
|
print(sigma.latency(read_fraction=0.5))
|
|
|
|
sigma = grid.strategy(read_fraction=0.5,
|
|
optimize='load',
|
|
latency_limit=seconds(4))
|
|
print(sigma)
|
|
print(sigma.capacity(read_fraction=0.5))
|
|
print(sigma.latency(read_fraction=0.5))
|
|
|
|
# grid.strategy(read_fraction=0.5,
|
|
# optimize='load',
|
|
# latency_limit=seconds(1))
|
|
# quoracle.quorum_system.NoStrategyFoundError: no strategy satisfies the given constraints
|
|
|
|
## Network Load
|
|
sigma = grid.strategy(read_fraction=0.5, optimize='network')
|
|
print(sigma)
|
|
print(sigma.network_load(read_fraction=0.5))
|
|
print(grid.network_load(read_fraction=0.5, optimize='network'))
|
|
sigma = grid.strategy(read_fraction=0.5,
|
|
optimize='network',
|
|
load_limit=1/2000,
|
|
latency_limit=seconds(4))
|
|
|
|
## Search
|
|
qs, sigma = search(nodes=[a, b, c, d, e, f],
|
|
resilience=1,
|
|
f=1,
|
|
read_fraction=0.75,
|
|
optimize='load',
|
|
latency_limit=seconds(4),
|
|
network_limit=4,
|
|
timeout=seconds(60))
|
|
print(qs)
|
|
print(sigma)
|
|
print(sigma.capacity(read_fraction=0.75))
|
|
print(sigma.latency(read_fraction=0.75))
|
|
print(sigma.network_load(read_fraction=0.75))
|