Add more entity passivation strategy traces and simulations (#30994)

* Add optimal clairvoyant algorithm to passivation strategy simulations

* Add natural zipfian distribution trace using text of Moby Dick

* Add some looping access pattern traces from the LIRS paper

* Add CloudPhysics access pattern trace from LIRS2 paper

* Add Wikipedia access pattern trace to passivation simulations
This commit is contained in:
Peter Vlugter 2021-12-16 23:04:18 +13:00 committed by GitHub
parent aa29071b96
commit 0c92cc573a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 3017 additions and 18 deletions

View file

@ -11,6 +11,14 @@
# ╔══════════╤═════════╤════════════╤═════════════╤══════════════╗ # ╔══════════╤═════════╤════════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║ # ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠══════════╪═════════╪════════════╪═════════════╪══════════════╣ # ╠══════════╪═════════╪════════════╪═════════════╪══════════════╣
# ║ OPT 1M │ 20.19 % │ 43,704,979 │ 34,879,633 │ 33,879,633 ║
# ╟──────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ OPT 2M │ 31.79 % │ 43,704,979 │ 29,810,905 │ 27,810,905 ║
# ╟──────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ OPT 4M │ 48.09 % │ 43,704,979 │ 22,685,636 │ 18,685,636 ║
# ╟──────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ OPT 8M │ 74.93 % │ 43,704,979 │ 10,957,661 │ 2,957,661 ║
# ╠══════════╪═════════╪════════════╪═════════════╪══════════════╣
# ║ LRU 1M │ 3.09 % │ 43,704,979 │ 42,356,500 │ 41,356,500 ║ # ║ LRU 1M │ 3.09 % │ 43,704,979 │ 42,356,500 │ 41,356,500 ║
# ╟──────────┼─────────┼────────────┼─────────────┼──────────────╢ # ╟──────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ LRU 2M │ 10.75 % │ 43,704,979 │ 39,007,141 │ 37,007,141 ║ # ║ LRU 2M │ 10.75 % │ 43,704,979 │ 39,007,141 │ 37,007,141 ║
@ -67,6 +75,34 @@ arc-traces=${?ARC_TRACES}
akka.cluster.sharding { akka.cluster.sharding {
passivation.simulator { passivation.simulator {
runs = [ runs = [
{
name = "OPT 1M"
shards = 100
regions = 10
pattern = arc-database
strategy = optimal-100k
},
{
name = "OPT 2M"
shards = 100
regions = 10
pattern = arc-database
strategy = optimal-200k
},
{
name = "OPT 4M"
shards = 100
regions = 10
pattern = arc-database
strategy = optimal-400k
},
{
name = "OPT 8M"
shards = 100
regions = 10
pattern = arc-database
strategy = optimal-800k
},
{ {
name = "LRU 1M" name = "LRU 1M"
shards = 100 shards = 100
@ -247,6 +283,34 @@ akka.cluster.sharding {
} }
} }
optimal-100k {
strategy = optimal
optimal {
per-region-limit = 100000
}
}
optimal-200k {
strategy = optimal
optimal {
per-region-limit = 200000
}
}
optimal-400k {
strategy = optimal
optimal {
per-region-limit = 400000
}
}
optimal-800k {
strategy = optimal
optimal {
per-region-limit = 800000
}
}
lru-100k { lru-100k {
strategy = least-recently-used strategy = least-recently-used
least-recently-used { least-recently-used {

View file

@ -11,6 +11,12 @@
# ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗ # ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║ # ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠════════════╪═════════╪════════════╪═════════════╪══════════════╣ # ╠════════════╪═════════╪════════════╪═════════════╪══════════════╣
# ║ OPT 250k │ 30.13 % │ 37,656,092 │ 26,309,294 │ 26,059,294 ║
# ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ OPT 500k │ 45.95 % │ 37,656,092 │ 20,354,161 │ 19,854,161 ║
# ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ OPT 1M │ 65.55 % │ 37,656,092 │ 12,970,868 │ 11,970,868 ║
# ╠════════════╪═════════╪════════════╪═════════════╪══════════════╣
# ║ LRU 250k │ 3.07 % │ 37,656,092 │ 36,498,516 │ 36,248,516 ║ # ║ LRU 250k │ 3.07 % │ 37,656,092 │ 36,498,516 │ 36,248,516 ║
# ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢ # ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ LRU 500k │ 7.53 % │ 37,656,092 │ 34,822,122 │ 34,322,122 ║ # ║ LRU 500k │ 7.53 % │ 37,656,092 │ 34,822,122 │ 34,322,122 ║
@ -55,6 +61,27 @@ arc-traces=${?ARC_TRACES}
akka.cluster.sharding { akka.cluster.sharding {
passivation.simulator { passivation.simulator {
runs = [ runs = [
{
name = "OPT 250k"
shards = 100
regions = 10
pattern = arc-search-merged
strategy = optimal-25k
},
{
name = "OPT 500k"
shards = 100
regions = 10
pattern = arc-search-merged
strategy = optimal-50k
},
{
name = "OPT 1M"
shards = 100
regions = 10
pattern = arc-search-merged
strategy = optimal-100k
},
{ {
name = "LRU 250k" name = "LRU 250k"
shards = 100 shards = 100
@ -193,6 +220,27 @@ akka.cluster.sharding {
} }
} }
optimal-25k {
strategy = optimal
optimal {
per-region-limit = 25000
}
}
optimal-50k {
strategy = optimal
optimal {
per-region-limit = 50000
}
}
optimal-100k {
strategy = optimal
optimal {
per-region-limit = 100000
}
}
lru-25k { lru-25k {
strategy = least-recently-used strategy = least-recently-used
least-recently-used { least-recently-used {

View file

@ -0,0 +1,506 @@
#
# Run the "glimpse" trace (gli.trace) from the authors of the LIRS algorithm.
#
# LIRS: An Efficient Low Inter-reference Recency Set Replacement Policy to Improve Buffer Cache Performance
# Song Jiang and Xiaodong Zhang
#
# Download traces from: https://github.com/zhongch4g/LIRS2
#
# > akka-cluster-sharding/Test/runMain akka.cluster.sharding.passivation.simulator.Simulator lirs-trace-glimpse
#
# ╔════════════╤═════════╤══════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ OPT 250 │ 17.70 % │ 6,016 │ 4,951 │ 4,701 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 500 │ 34.33 % │ 6,016 │ 3,951 │ 3,451 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 1000 │ 53.14 % │ 6,016 │ 2,819 │ 1,819 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 1500 │ 57.95 % │ 6,016 │ 2,530 │ 1,030 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LRU 250 │ 0.91 % │ 6,016 │ 5,961 │ 5,711 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 500 │ 0.95 % │ 6,016 │ 5,959 │ 5,459 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 1000 │ 11.20 % │ 6,016 │ 5,342 │ 4,342 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 1500 │ 36.55 % │ 6,016 │ 3,817 │ 2,317 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ SLRU 250 │ 1.38 % │ 6,016 │ 5,933 │ 5,683 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 500 │ 1.38 % │ 6,016 │ 5,933 │ 5,433 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 1000 │ 31.33 % │ 6,016 │ 4,131 │ 3,131 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 1500 │ 51.85 % │ 6,016 │ 2,897 │ 1,397 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ S4LRU 250 │ 1.38 % │ 6,016 │ 5,933 │ 5,693 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 500 │ 1.38 % │ 6,016 │ 5,933 │ 5,453 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 1000 │ 19.70 % │ 6,016 │ 4,831 │ 3,831 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 1500 │ 48.02 % │ 6,016 │ 3,127 │ 1,647 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ MRU 250 │ 14.78 % │ 6,016 │ 5,127 │ 4,877 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 500 │ 31.40 % │ 6,016 │ 4,127 │ 3,627 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 1000 │ 48.62 % │ 6,016 │ 3,091 │ 2,091 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 1500 │ 53.37 % │ 6,016 │ 2,805 │ 1,305 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFU 250 │ 1.38 % │ 6,016 │ 5,933 │ 5,683 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 500 │ 1.38 % │ 6,016 │ 5,933 │ 5,433 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 1000 │ 31.33 % │ 6,016 │ 4,131 │ 3,131 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 1500 │ 51.85 % │ 6,016 │ 2,897 │ 1,397 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFUDA 250 │ 1.11 % │ 6,016 │ 5,949 │ 5,699 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 500 │ 1.25 % │ 6,016 │ 5,941 │ 5,441 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 1000 │ 16.37 % │ 6,016 │ 5,031 │ 4,031 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 1500 │ 51.85 % │ 6,016 │ 2,897 │ 1,397 ║
# ╚════════════╧═════════╧══════════╧═════════════╧══════════════╝
#
lirs-traces="lirs-traces"
lirs-traces=${?LIRS_TRACES}
akka.cluster.sharding {
passivation.simulator {
runs = [
{
name = "OPT 250"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = optimal-250
},
{
name = "OPT 500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = optimal-500
},
{
name = "OPT 1000"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = optimal-1000
},
{
name = "OPT 1500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = optimal-1500
},
{
name = "LRU 250"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lru-250
},
{
name = "LRU 500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lru-500
},
{
name = "LRU 1000"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lru-1000
},
{
name = "LRU 1500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lru-1500
},
{
name = "SLRU 250"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = slru-250
},
{
name = "SLRU 500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = slru-500
},
{
name = "SLRU 1000"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = slru-1000
},
{
name = "SLRU 1500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = slru-1500
},
{
name = "S4LRU 250"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = s4lru-250
},
{
name = "S4LRU 500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = s4lru-500
},
{
name = "S4LRU 1000"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = s4lru-1000
},
{
name = "S4LRU 1500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = s4lru-1500
},
{
name = "MRU 250"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = mru-250
},
{
name = "MRU 500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = mru-500
},
{
name = "MRU 1000"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = mru-1000
},
{
name = "MRU 1500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = mru-1500
},
{
name = "LFU 250"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfu-250
},
{
name = "LFU 500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfu-500
},
{
name = "LFU 1000"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfu-1000
},
{
name = "LFU 1500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfu-1500
},
{
name = "LFUDA 250"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfuda-250
},
{
name = "LFUDA 500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfuda-500
},
{
name = "LFUDA 1000"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfuda-1000
},
{
name = "LFUDA 1500"
shards = 10
regions = 1
pattern = lirs-glimpse
strategy = lfuda-1500
},
]
print-detailed-stats = true
lirs-glimpse {
pattern = trace
trace {
format = lirs
path = ${lirs-traces}"/gli.trace"
}
}
optimal-250 {
strategy = optimal
optimal {
per-region-limit = 250
}
}
optimal-500 {
strategy = optimal
optimal {
per-region-limit = 500
}
}
optimal-1000 {
strategy = optimal
optimal {
per-region-limit = 1000
}
}
optimal-1500 {
strategy = optimal
optimal {
per-region-limit = 1500
}
}
lru-250 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 250
}
}
lru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
}
}
lru-1000 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1000
}
}
lru-1500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1500
}
}
slru-250 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 250
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-1000 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1000
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-1500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1500
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
s4lru-250 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 250
segmented.levels = 4
}
}
s4lru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
segmented.levels = 4
}
}
s4lru-1000 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1000
segmented.levels = 4
}
}
s4lru-1500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1500
segmented.levels = 4
}
}
mru-250 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 250
}
}
mru-500 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 500
}
}
mru-1000 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 1000
}
}
mru-1500 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 1500
}
}
lfu-250 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 250
}
}
lfu-500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 500
}
}
lfu-1000 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1000
}
}
lfu-1500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1500
}
}
lfuda-250 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 250
dynamic-aging = on
}
}
lfuda-500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 500
dynamic-aging = on
}
}
lfuda-1000 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1000
dynamic-aging = on
}
}
lfuda-1500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1500
dynamic-aging = on
}
}
}
}

View file

@ -0,0 +1,624 @@
#
# Run the "multi3" trace (multi3.trace) from the authors of the LIRS algorithm.
#
# LIRS: An Efficient Low Inter-reference Recency Set Replacement Policy to Improve Buffer Cache Performance
# Song Jiang and Xiaodong Zhang
#
# Download traces from: https://github.com/zhongch4g/LIRS2
#
# > akka-cluster-sharding/Test/runMain akka.cluster.sharding.passivation.simulator.Simulator lirs-trace-multi
#
# ╔════════════╤═════════╤══════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ OPT 100 │ 31.20 % │ 30,241 │ 20,807 │ 20,707 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 200 │ 38.47 % │ 30,241 │ 18,607 │ 18,407 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 400 │ 47.14 % │ 30,241 │ 15,986 │ 15,586 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 800 │ 53.53 % │ 30,241 │ 14,054 │ 13,254 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 1600 │ 64.14 % │ 30,241 │ 10,844 │ 9,244 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LRU 100 │ 6.53 % │ 30,241 │ 28,266 │ 28,166 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 200 │ 14.38 % │ 30,241 │ 25,891 │ 25,691 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 400 │ 27.55 % │ 30,241 │ 21,909 │ 21,509 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 800 │ 35.97 % │ 30,241 │ 19,364 │ 18,564 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 1600 │ 44.23 % │ 30,241 │ 16,865 │ 15,265 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ SLRU 100 │ 9.22 % │ 30,241 │ 27,454 │ 27,354 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 200 │ 22.41 % │ 30,241 │ 23,463 │ 23,263 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 400 │ 29.94 % │ 30,241 │ 21,186 │ 20,786 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 800 │ 37.30 % │ 30,241 │ 18,961 │ 18,161 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 1600 │ 46.51 % │ 30,241 │ 16,177 │ 14,577 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ S4LRU 100 │ 8.43 % │ 30,241 │ 27,691 │ 27,611 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 200 │ 22.62 % │ 30,241 │ 23,401 │ 23,201 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 400 │ 30.10 % │ 30,241 │ 21,139 │ 20,739 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 800 │ 37.30 % │ 30,241 │ 18,962 │ 18,162 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 1600 │ 46.51 % │ 30,241 │ 16,177 │ 14,577 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ MRU 100 │ 2.41 % │ 30,241 │ 29,512 │ 29,412 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 200 │ 4.20 % │ 30,241 │ 28,970 │ 28,770 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 400 │ 7.21 % │ 30,241 │ 28,062 │ 27,662 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 800 │ 14.11 % │ 30,241 │ 25,973 │ 25,173 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 1600 │ 26.31 % │ 30,241 │ 22,284 │ 20,684 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFU 100 │ 8.88 % │ 30,241 │ 27,557 │ 27,457 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 200 │ 22.14 % │ 30,241 │ 23,547 │ 23,347 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 400 │ 29.85 % │ 30,241 │ 21,213 │ 20,813 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 800 │ 37.30 % │ 30,241 │ 18,961 │ 18,161 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 1600 │ 46.51 % │ 30,241 │ 16,177 │ 14,577 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFUDA 100 │ 10.16 % │ 30,241 │ 27,168 │ 27,068 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 200 │ 22.99 % │ 30,241 │ 23,290 │ 23,090 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 400 │ 30.50 % │ 30,241 │ 21,019 │ 20,619 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 800 │ 37.25 % │ 30,241 │ 18,977 │ 18,177 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 1600 │ 46.21 % │ 30,241 │ 16,267 │ 14,667 ║
# ╚════════════╧═════════╧══════════╧═════════════╧══════════════╝
#
lirs-traces="lirs-traces"
lirs-traces=${?LIRS_TRACES}
akka.cluster.sharding {
passivation.simulator {
runs = [
{
name = "OPT 100"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = optimal-100
},
{
name = "OPT 200"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = optimal-200
},
{
name = "OPT 400"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = optimal-400
},
{
name = "OPT 800"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = optimal-800
},
{
name = "OPT 1600"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = optimal-1600
},
{
name = "LRU 100"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lru-100
},
{
name = "LRU 200"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lru-200
},
{
name = "LRU 400"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lru-400
},
{
name = "LRU 800"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lru-800
},
{
name = "LRU 1600"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lru-1600
},
{
name = "SLRU 100"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = slru-100
},
{
name = "SLRU 200"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = slru-200
},
{
name = "SLRU 400"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = slru-400
},
{
name = "SLRU 800"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = slru-800
},
{
name = "SLRU 1600"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = slru-1600
},
{
name = "S4LRU 100"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = s4lru-100
},
{
name = "S4LRU 200"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = s4lru-200
},
{
name = "S4LRU 400"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = s4lru-400
},
{
name = "S4LRU 800"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = s4lru-800
},
{
name = "S4LRU 1600"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = s4lru-1600
},
{
name = "MRU 100"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = mru-100
},
{
name = "MRU 200"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = mru-200
},
{
name = "MRU 400"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = mru-400
},
{
name = "MRU 800"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = mru-800
},
{
name = "MRU 1600"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = mru-1600
},
{
name = "LFU 100"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfu-100
},
{
name = "LFU 200"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfu-200
},
{
name = "LFU 400"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfu-400
},
{
name = "LFU 800"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfu-800
},
{
name = "LFU 1600"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfu-1600
},
{
name = "LFUDA 100"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfuda-100
},
{
name = "LFUDA 200"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfuda-200
},
{
name = "LFUDA 400"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfuda-400
},
{
name = "LFUDA 800"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfuda-800
},
{
name = "LFUDA 1600"
shards = 10
regions = 1
pattern = lirs-multi3
strategy = lfuda-1600
},
]
print-detailed-stats = true
lirs-multi3 {
pattern = trace
trace {
format = lirs
path = ${lirs-traces}"/multi3.trace"
}
}
optimal-100 {
strategy = optimal
optimal {
per-region-limit = 100
}
}
optimal-200 {
strategy = optimal
optimal {
per-region-limit = 200
}
}
optimal-400 {
strategy = optimal
optimal {
per-region-limit = 400
}
}
optimal-800 {
strategy = optimal
optimal {
per-region-limit = 800
}
}
optimal-1600 {
strategy = optimal
optimal {
per-region-limit = 1600
}
}
lru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
}
}
lru-200 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 200
}
}
lru-400 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 400
}
}
lru-800 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 800
}
}
lru-1600 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1600
}
}
slru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-200 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 200
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-400 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 400
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-800 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 800
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-1600 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1600
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
s4lru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
segmented.levels = 4
}
}
s4lru-200 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 200
segmented.levels = 4
}
}
s4lru-400 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 400
segmented.levels = 4
}
}
s4lru-800 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 800
segmented.levels = 4
}
}
s4lru-1600 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1600
segmented.levels = 4
}
}
mru-100 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 100
}
}
mru-200 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 200
}
}
mru-400 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 400
}
}
mru-800 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 800
}
}
mru-1600 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 1600
}
}
lfu-100 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 100
}
}
lfu-200 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 200
}
}
lfu-400 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 400
}
}
lfu-800 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 800
}
}
lfu-1600 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1600
}
}
lfuda-100 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 100
dynamic-aging = on
}
}
lfuda-200 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 200
dynamic-aging = on
}
}
lfuda-400 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 400
dynamic-aging = on
}
}
lfuda-800 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 800
dynamic-aging = on
}
}
lfuda-1600 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1600
dynamic-aging = on
}
}
}
}

View file

@ -0,0 +1,506 @@
#
# Run the "postgres" trace (ps.trace) from the authors of the LIRS algorithm.
#
# LIRS: An Efficient Low Inter-reference Recency Set Replacement Policy to Improve Buffer Cache Performance
# Song Jiang and Xiaodong Zhang
#
# Download traces from: https://github.com/zhongch4g/LIRS2
#
# > akka-cluster-sharding/Test/runMain akka.cluster.sharding.passivation.simulator.Simulator lirs-trace-postgres
#
# ╔════════════╤═════════╤══════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ OPT 125 │ 35.16 % │ 10,448 │ 6,774 │ 6,654 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 250 │ 53.33 % │ 10,448 │ 4,876 │ 4,626 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 500 │ 58.12 % │ 10,448 │ 4,376 │ 3,876 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 1000 │ 67.69 % │ 10,448 │ 3,376 │ 2,376 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LRU 125 │ 12.19 % │ 10,448 │ 9,174 │ 9,054 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 250 │ 13.95 % │ 10,448 │ 8,991 │ 8,741 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 500 │ 48.55 % │ 10,448 │ 5,376 │ 4,876 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 1000 │ 48.55 % │ 10,448 │ 5,376 │ 4,376 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ SLRU 125 │ 9.34 % │ 10,448 │ 9,472 │ 9,362 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 250 │ 16.80 % │ 10,448 │ 8,693 │ 8,443 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 500 │ 52.59 % │ 10,448 │ 4,953 │ 4,453 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 1000 │ 52.59 % │ 10,448 │ 4,953 │ 3,953 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ S4LRU 125 │ 9.34 % │ 10,448 │ 9,472 │ 9,352 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 250 │ 16.80 % │ 10,448 │ 8,693 │ 8,453 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 500 │ 51.95 % │ 10,448 │ 5,020 │ 4,540 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 1000 │ 52.59 % │ 10,448 │ 4,953 │ 3,953 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ MRU 125 │ 14.23 % │ 10,448 │ 8,961 │ 8,841 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 250 │ 30.84 % │ 10,448 │ 7,226 │ 6,976 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 500 │ 45.67 % │ 10,448 │ 5,676 │ 5,176 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 1000 │ 64.41 % │ 10,448 │ 3,718 │ 2,718 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFU 125 │ 9.34 % │ 10,448 │ 9,472 │ 9,352 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 250 │ 16.80 % │ 10,448 │ 8,693 │ 8,443 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 500 │ 52.59 % │ 10,448 │ 4,953 │ 4,453 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 1000 │ 52.59 % │ 10,448 │ 4,953 │ 3,953 ║
# ╠════════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFUDA 125 │ 12.89 % │ 10,448 │ 9,101 │ 8,981 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 250 │ 16.79 % │ 10,448 │ 8,694 │ 8,444 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 500 │ 52.58 % │ 10,448 │ 4,954 │ 4,454 ║
# ╟────────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 1000 │ 52.58 % │ 10,448 │ 4,954 │ 3,954 ║
# ╚════════════╧═════════╧══════════╧═════════════╧══════════════╝
#
lirs-traces="lirs-traces"
lirs-traces=${?LIRS_TRACES}
akka.cluster.sharding {
passivation.simulator {
runs = [
{
name = "OPT 125"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = optimal-125
},
{
name = "OPT 250"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = optimal-250
},
{
name = "OPT 500"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = optimal-500
},
{
name = "OPT 1000"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = optimal-1000
},
{
name = "LRU 125"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lru-125
},
{
name = "LRU 250"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lru-250
},
{
name = "LRU 500"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lru-500
},
{
name = "LRU 1000"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lru-1000
},
{
name = "SLRU 125"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = slru-125
},
{
name = "SLRU 250"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = slru-250
},
{
name = "SLRU 500"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = slru-500
},
{
name = "SLRU 1000"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = slru-1000
},
{
name = "S4LRU 125"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = s4lru-125
},
{
name = "S4LRU 250"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = s4lru-250
},
{
name = "S4LRU 500"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = s4lru-500
},
{
name = "S4LRU 1000"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = s4lru-1000
},
{
name = "MRU 125"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = mru-125
},
{
name = "MRU 250"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = mru-250
},
{
name = "MRU 500"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = mru-500
},
{
name = "MRU 1000"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = mru-1000
},
{
name = "LFU 125"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfu-125
},
{
name = "LFU 250"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfu-250
},
{
name = "LFU 500"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfu-500
},
{
name = "LFU 1000"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfu-1000
},
{
name = "LFUDA 125"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfuda-125
},
{
name = "LFUDA 250"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfuda-250
},
{
name = "LFUDA 500"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfuda-500
},
{
name = "LFUDA 1000"
shards = 10
regions = 1
pattern = lirs-postgres
strategy = lfuda-1000
},
]
print-detailed-stats = true
lirs-postgres {
pattern = trace
trace {
format = lirs
path = ${lirs-traces}"/ps.trace"
}
}
optimal-125 {
strategy = optimal
optimal {
per-region-limit = 125
}
}
optimal-250 {
strategy = optimal
optimal {
per-region-limit = 250
}
}
optimal-500 {
strategy = optimal
optimal {
per-region-limit = 500
}
}
optimal-1000 {
strategy = optimal
optimal {
per-region-limit = 1000
}
}
lru-125 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 125
}
}
lru-250 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 250
}
}
lru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
}
}
lru-1000 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1000
}
}
slru-125 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 125
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-250 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 250
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-1000 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1000
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
s4lru-125 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 125
segmented.levels = 4
}
}
s4lru-250 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 250
segmented.levels = 4
}
}
s4lru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
segmented.levels = 4
}
}
s4lru-1000 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 1000
segmented.levels = 4
}
}
mru-125 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 125
}
}
mru-250 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 250
}
}
mru-500 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 500
}
}
mru-1000 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 1000
}
}
lfu-125 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 125
}
}
lfu-250 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 250
}
}
lfu-500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 500
}
}
lfu-1000 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1000
}
}
lfuda-125 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 125
dynamic-aging = on
}
}
lfuda-250 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 250
dynamic-aging = on
}
}
lfuda-500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 500
dynamic-aging = on
}
}
lfuda-1000 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 1000
dynamic-aging = on
}
}
}
}

View file

@ -0,0 +1,509 @@
#
# Run the "w106" binary trace (w106.trace) from the authors of the LIRS2 algorithm.
#
# LIRS2: An Improved LIRS Replacement Algorithm
# Chen Zhong, Xingsheng Zhao, and Song Jiang
#
# Download traces from: https://github.com/zhongch4g/LIRS2
#
# This trace is a week-long virtual disk trace collected by CloudPhysics's caching analytics service.
# The trace has just over 275k unique ids. The most popular 100 ids account for around 34% of accesses.
#
# > akka-cluster-sharding/Test/runMain akka.cluster.sharding.passivation.simulator.Simulator lirs2-trace-w106
#
# ╔═══════════╤═════════╤═══════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠═══════════╪═════════╪═══════════╪═════════════╪══════════════╣
# ║ OPT 50 │ 57.92 % │ 5,292,456 │ 2,226,826 │ 2,226,776 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ OPT 100 │ 66.17 % │ 5,292,456 │ 1,790,310 │ 1,790,210 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ OPT 200 │ 71.69 % │ 5,292,456 │ 1,498,368 │ 1,498,168 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ OPT 500 │ 77.20 % │ 5,292,456 │ 1,206,445 │ 1,205,945 ║
# ╠═══════════╪═════════╪═══════════╪═════════════╪══════════════╣
# ║ LRU 50 │ 45.35 % │ 5,292,456 │ 2,892,538 │ 2,892,488 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LRU 100 │ 53.47 % │ 5,292,456 │ 2,462,659 │ 2,462,559 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LRU 200 │ 64.96 % │ 5,292,456 │ 1,854,353 │ 1,854,153 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LRU 500 │ 70.97 % │ 5,292,456 │ 1,536,203 │ 1,535,703 ║
# ╠═══════════╪═════════╪═══════════╪═════════════╪══════════════╣
# ║ SLRU 50 │ 41.44 % │ 5,292,456 │ 3,099,112 │ 3,099,062 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ SLRU 100 │ 52.52 % │ 5,292,456 │ 2,513,049 │ 2,512,949 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ SLRU 200 │ 60.42 % │ 5,292,456 │ 2,094,936 │ 2,094,736 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ SLRU 500 │ 70.02 % │ 5,292,456 │ 1,586,665 │ 1,586,165 ║
# ╠═══════════╪═════════╪═══════════╪═════════════╪══════════════╣
# ║ S4LRU 50 │ 39.87 % │ 5,292,456 │ 3,182,347 │ 3,182,307 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ S4LRU 100 │ 54.30 % │ 5,292,456 │ 2,418,459 │ 2,418,359 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ S4LRU 200 │ 63.50 % │ 5,292,456 │ 1,931,759 │ 1,931,559 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ S4LRU 500 │ 70.68 % │ 5,292,456 │ 1,551,818 │ 1,551,318 ║
# ╠═══════════╪═════════╪═══════════╪═════════════╪══════════════╣
# ║ MRU 50 │ 22.23 % │ 5,292,456 │ 4,116,089 │ 4,116,039 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ MRU 100 │ 22.36 % │ 5,292,456 │ 4,109,089 │ 4,108,989 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ MRU 200 │ 22.68 % │ 5,292,456 │ 4,092,384 │ 4,092,184 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ MRU 500 │ 23.53 % │ 5,292,456 │ 4,046,928 │ 4,046,428 ║
# ╠═══════════╪═════════╪═══════════╪═════════════╪══════════════╣
# ║ LFU 50 │ 35.92 % │ 5,292,456 │ 3,391,594 │ 3,391,544 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LFU 100 │ 42.52 % │ 5,292,456 │ 3,041,915 │ 3,041,815 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LFU 200 │ 48.42 % │ 5,292,456 │ 2,729,711 │ 2,729,511 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LFU 500 │ 53.57 % │ 5,292,456 │ 2,457,445 │ 2,456,945 ║
# ╠═══════════╪═════════╪═══════════╪═════════════╪══════════════╣
# ║ LFUDA 50 │ 46.11 % │ 5,292,456 │ 2,851,965 │ 2,851,915 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LFUDA 100 │ 55.62 % │ 5,292,456 │ 2,348,665 │ 2,348,565 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LFUDA 200 │ 64.83 % │ 5,292,456 │ 1,861,307 │ 1,861,107 ║
# ╟───────────┼─────────┼───────────┼─────────────┼──────────────╢
# ║ LFUDA 500 │ 71.38 % │ 5,292,456 │ 1,514,631 │ 1,514,131 ║
# ╚═══════════╧═════════╧═══════════╧═════════════╧══════════════╝
#
lirs2-traces="lirs2-traces"
lirs2-traces=${?LIRS2_TRACES}
akka.cluster.sharding {
passivation.simulator {
runs = [
{
name = "OPT 50"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = optimal-50
},
{
name = "OPT 100"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = optimal-100
},
{
name = "OPT 200"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = optimal-200
},
{
name = "OPT 500"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = optimal-500
},
{
name = "LRU 50"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lru-50
},
{
name = "LRU 100"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lru-100
},
{
name = "LRU 200"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lru-200
},
{
name = "LRU 500"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lru-500
},
{
name = "SLRU 50"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = slru-50
},
{
name = "SLRU 100"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = slru-100
},
{
name = "SLRU 200"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = slru-200
},
{
name = "SLRU 500"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = slru-500
},
{
name = "S4LRU 50"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = s4lru-50
},
{
name = "S4LRU 100"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = s4lru-100
},
{
name = "S4LRU 200"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = s4lru-200
},
{
name = "S4LRU 500"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = s4lru-500
},
{
name = "MRU 50"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = mru-50
},
{
name = "MRU 100"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = mru-100
},
{
name = "MRU 200"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = mru-200
},
{
name = "MRU 500"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = mru-500
},
{
name = "LFU 50"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfu-50
},
{
name = "LFU 100"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfu-100
},
{
name = "LFU 200"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfu-200
},
{
name = "LFU 500"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfu-500
},
{
name = "LFUDA 50"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfuda-50
},
{
name = "LFUDA 100"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfuda-100
},
{
name = "LFUDA 200"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfuda-200
},
{
name = "LFUDA 500"
shards = 5
regions = 1
pattern = lirs2-w106
strategy = lfuda-500
},
]
print-detailed-stats = true
lirs2-w106 {
pattern = trace
trace {
format = lirs2
path = ${lirs2-traces}"/w106.trace"
}
}
optimal-50 {
strategy = optimal
optimal {
per-region-limit = 50
}
}
optimal-100 {
strategy = optimal
optimal {
per-region-limit = 100
}
}
optimal-200 {
strategy = optimal
optimal {
per-region-limit = 200
}
}
optimal-500 {
strategy = optimal
optimal {
per-region-limit = 500
}
}
lru-50 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 50
}
}
lru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
}
}
lru-200 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 200
}
}
lru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
}
}
slru-50 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 50
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-200 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 200
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
s4lru-50 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 50
segmented.levels = 4
}
}
s4lru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
segmented.levels = 4
}
}
s4lru-200 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 200
segmented.levels = 4
}
}
s4lru-500 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 500
segmented.levels = 4
}
}
mru-50 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 50
}
}
mru-100 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 100
}
}
mru-200 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 200
}
}
mru-500 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 500
}
}
lfu-50 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 50
}
}
lfu-100 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 100
}
}
lfu-200 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 200
}
}
lfu-500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 500
}
}
lfuda-50 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 50
dynamic-aging = on
}
}
lfuda-100 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 100
dynamic-aging = on
}
}
lfuda-200 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 200
dynamic-aging = on
}
}
lfuda-500 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 500
dynamic-aging = on
}
}
}
}

View file

@ -8,6 +8,8 @@
# ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗ # ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║ # ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠════════════╪═════════╪════════════╪═════════════╪══════════════╣ # ╠════════════╪═════════╪════════════╪═════════════╪══════════════╣
# ║ OPT 100k │ 53.75 % │ 50,000,000 │ 23,125,433 │ 23,025,433 ║
# ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ LRU 100k │ 40.47 % │ 50,000,000 │ 29,764,380 │ 29,664,380 ║ # ║ LRU 100k │ 40.47 % │ 50,000,000 │ 29,764,380 │ 29,664,380 ║
# ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢ # ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ SLRU 100k │ 47.14 % │ 50,000,000 │ 26,428,026 │ 26,328,026 ║ # ║ SLRU 100k │ 47.14 % │ 50,000,000 │ 26,428,026 │ 26,328,026 ║
@ -26,6 +28,8 @@
# ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗ # ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║ # ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠════════════╪═════════╪════════════╪═════════════╪══════════════╣ # ╠════════════╪═════════╪════════════╪═════════════╪══════════════╣
# ║ OPT 100k │ 32.31 % │ 50,000,000 │ 33,846,785 │ 33,746,785 ║
# ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ LRU 100k │ 22.50 % │ 50,000,000 │ 38,749,623 │ 38,649,623 ║ # ║ LRU 100k │ 22.50 % │ 50,000,000 │ 38,749,623 │ 38,649,623 ║
# ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢ # ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢
# ║ SLRU 100k │ 22.63 % │ 50,000,000 │ 38,682,890 │ 38,582,890 ║ # ║ SLRU 100k │ 22.63 % │ 50,000,000 │ 38,682,890 │ 38,582,890 ║
@ -43,6 +47,14 @@
akka.cluster.sharding { akka.cluster.sharding {
passivation.simulator { passivation.simulator {
runs = [ runs = [
{
name = "OPT 100k"
shards = 100
regions = 10
pattern = scrambled-zipfian
# pattern = shifting-scrambled-zipfian
strategy = optimal-10k
},
{ {
name = "LRU 100k" name = "LRU 100k"
shards = 100 shards = 100
@ -126,6 +138,15 @@ akka.cluster.sharding {
} }
} }
# Optimal (clairvoyant) strategy with 10k limit in each of 10 regions
# total limit across cluster of 100k (1% of id space)
optimal-10k {
strategy = optimal
optimal {
per-region-limit = 10000
}
}
# LRU strategy with 10k limit in each of 10 regions # LRU strategy with 10k limit in each of 10 regions
# total limit across cluster of 100k (1% of id space) # total limit across cluster of 100k (1% of id space)
lru-10k { lru-10k {

View file

@ -0,0 +1,384 @@
#
# Run against the text of Moby Dick, for a natural zipfian-like distribution.
#
# Text can be downloaded from: https://www.gutenberg.org/files/2701/2701-0.txt
#
# > akka-cluster-sharding/Test/runMain akka.cluster.sharding.passivation.simulator.Simulator text-moby-dick
#
# ╔═══════════╤═════════╤══════════╤═════════════╤══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠═══════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ OPT 25 │ 45.52 % │ 216,904 │ 118,161 │ 118,136 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 50 │ 54.52 % │ 216,904 │ 98,658 │ 98,608 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ OPT 100 │ 62.62 % │ 216,904 │ 81,073 │ 80,973 ║
# ╠═══════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LRU 25 │ 21.84 % │ 216,904 │ 169,542 │ 169,517 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 50 │ 32.48 % │ 216,904 │ 146,444 │ 146,394 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LRU 100 │ 43.41 % │ 216,904 │ 122,750 │ 122,650 ║
# ╠═══════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ SLRU 25 │ 30.22 % │ 216,904 │ 151,349 │ 151,324 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 50 │ 40.14 % │ 216,904 │ 129,845 │ 129,795 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ SLRU 100 │ 50.10 % │ 216,904 │ 108,241 │ 108,141 ║
# ╠═══════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ S4LRU 25 │ 30.19 % │ 216,904 │ 151,422 │ 151,398 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 50 │ 40.15 % │ 216,904 │ 129,816 │ 129,768 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ S4LRU 100 │ 50.53 % │ 216,904 │ 107,304 │ 107,204 ║
# ╠═══════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ MRU 25 │ 0.30 % │ 216,904 │ 216,250 │ 216,225 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 50 │ 0.46 % │ 216,904 │ 215,899 │ 215,849 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ MRU 100 │ 0.71 % │ 216,904 │ 215,359 │ 215,259 ║
# ╠═══════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFU 25 │ 24.55 % │ 216,904 │ 163,651 │ 163,626 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 50 │ 33.91 % │ 216,904 │ 143,345 │ 143,295 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFU 100 │ 43.58 % │ 216,904 │ 122,378 │ 122,278 ║
# ╠═══════════╪═════════╪══════════╪═════════════╪══════════════╣
# ║ LFUDA 25 │ 30.80 % │ 216,904 │ 150,106 │ 150,081 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 50 │ 40.90 % │ 216,904 │ 128,180 │ 128,130 ║
# ╟───────────┼─────────┼──────────┼─────────────┼──────────────╢
# ║ LFUDA 100 │ 50.79 % │ 216,904 │ 106,731 │ 106,631 ║
# ╚═══════════╧═════════╧══════════╧═════════════╧══════════════╝
#
text-traces="text-traces"
text-traces=${?TEXT_TRACES}
akka.cluster.sharding {
passivation.simulator {
runs = [
{
name = "OPT 25"
shards = 1
regions = 1
pattern = moby-dick
strategy = optimal-25
},
{
name = "OPT 50"
shards = 1
regions = 1
pattern = moby-dick
strategy = optimal-50
},
{
name = "OPT 100"
shards = 1
regions = 1
pattern = moby-dick
strategy = optimal-100
},
{
name = "LRU 25"
shards = 1
regions = 1
pattern = moby-dick
strategy = lru-25
},
{
name = "LRU 50"
shards = 1
regions = 1
pattern = moby-dick
strategy = lru-50
},
{
name = "LRU 100"
shards = 1
regions = 1
pattern = moby-dick
strategy = lru-100
},
{
name = "SLRU 25"
shards = 1
regions = 1
pattern = moby-dick
strategy = slru-25
},
{
name = "SLRU 50"
shards = 1
regions = 1
pattern = moby-dick
strategy = slru-50
},
{
name = "SLRU 100"
shards = 1
regions = 1
pattern = moby-dick
strategy = slru-100
},
{
name = "S4LRU 25"
shards = 1
regions = 1
pattern = moby-dick
strategy = s4lru-25
},
{
name = "S4LRU 50"
shards = 1
regions = 1
pattern = moby-dick
strategy = s4lru-50
},
{
name = "S4LRU 100"
shards = 1
regions = 1
pattern = moby-dick
strategy = s4lru-100
},
{
name = "MRU 25"
shards = 1
regions = 1
pattern = moby-dick
strategy = mru-25
},
{
name = "MRU 50"
shards = 1
regions = 1
pattern = moby-dick
strategy = mru-50
},
{
name = "MRU 100"
shards = 1
regions = 1
pattern = moby-dick
strategy = mru-100
},
{
name = "LFU 25"
shards = 1
regions = 1
pattern = moby-dick
strategy = lfu-25
},
{
name = "LFU 50"
shards = 1
regions = 1
pattern = moby-dick
strategy = lfu-50
},
{
name = "LFU 100"
shards = 1
regions = 1
pattern = moby-dick
strategy = lfu-100
},
{
name = "LFUDA 25"
shards = 1
regions = 1
pattern = moby-dick
strategy = lfuda-25
},
{
name = "LFUDA 50"
shards = 1
regions = 1
pattern = moby-dick
strategy = lfuda-50
},
{
name = "LFUDA 100"
shards = 1
regions = 1
pattern = moby-dick
strategy = lfuda-100
},
]
# Moby Dick text as a trace
moby-dick {
pattern = trace
trace {
format = text
path = ${text-traces}"/moby-dick.txt"
}
}
optimal-25 {
strategy = optimal
optimal {
per-region-limit = 25
}
}
optimal-50 {
strategy = optimal
optimal {
per-region-limit = 50
}
}
optimal-100 {
strategy = optimal
optimal {
per-region-limit = 100
}
}
lru-25 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 25
}
}
lru-50 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 50
}
}
lru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
}
}
slru-25 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 25
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-50 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 50
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
slru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
s4lru-25 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 25
segmented.levels = 4
}
}
s4lru-50 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 50
segmented.levels = 4
}
}
s4lru-100 {
strategy = least-recently-used
least-recently-used {
per-region-limit = 100
segmented.levels = 4
}
}
mru-25 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 25
}
}
mru-50 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 50
}
}
mru-100 {
strategy = most-recently-used
most-recently-used {
per-region-limit = 100
}
}
lfu-25 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 25
}
}
lfu-50 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 50
}
}
lfu-100 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 100
}
}
lfuda-25 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 25
dynamic-aging = on
}
}
lfuda-50 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 50
dynamic-aging = on
}
}
lfuda-100 {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 100
dynamic-aging = on
}
}
}
}

View file

@ -0,0 +1,141 @@
#
# Run the 14-day Wikipedia trace from 2018 (wiki2018.tr) from the LRB simulator.
#
# Learning Relaxed Belady for Content Distribution Network Caching
# Zhenyu Song, Daniel S. Berger, Kai Li, Wyatt Lloyd
#
# Download traces from the simulator (uncompressed trace is 54 GB):
# https://github.com/sunnyszy/lrb#traces
#
# Trace is 2.8 billion accesses with around 37.5 million unique ids.
# Active entity limit of 100k is just over 0.1% of the id space.
# The most popular 100k ids account for almost half of the accesses.
#
# > akka-cluster-sharding/Test/runMain akka.cluster.sharding.passivation.simulator.Simulator wikipedia-trace-2018
#
# ╔════════════╤═════════╤═══════════════╤═══════════════╤═══════════════╗
# ║ Run │ Active │ Accesses │ Activations │ Passivations ║
# ╠════════════╪═════════╪═══════════════╪═══════════════╪═══════════════╣
# ║ LRU 100k │ 53.48 % │ 2,800,000,000 │ 1,302,519,161 │ 1,302,419,161 ║
# ╟────────────┼─────────┼───────────────┼───────────────┼───────────────╢
# ║ SLRU 100k │ 60.89 % │ 2,800,000,000 │ 1,095,063,465 │ 1,094,963,465 ║
# ╟────────────┼─────────┼───────────────┼───────────────┼───────────────╢
# ║ S4LRU 100k │ 60.66 % │ 2,800,000,000 │ 1,101,617,318 │ 1,101,517,318 ║
# ╟────────────┼─────────┼───────────────┼───────────────┼───────────────╢
# ║ MRU 100k │ 5.70 % │ 2,800,000,000 │ 2,640,279,048 │ 2,640,179,048 ║
# ╟────────────┼─────────┼───────────────┼───────────────┼───────────────╢
# ║ LFU 100k │ 58.17 % │ 2,800,000,000 │ 1,171,104,161 │ 1,171,004,161 ║
# ╟────────────┼─────────┼───────────────┼───────────────┼───────────────╢
# ║ LFUDA 100k │ 60.01 % │ 2,800,000,000 │ 1,119,687,614 │ 1,119,587,614 ║
# ╚════════════╧═════════╧═══════════════╧═══════════════╧═══════════════╝
#
wiki-traces="wiki-traces"
wiki-traces=${?WIKI_TRACES}
akka.cluster.sharding {
passivation.simulator {
runs = [
{
name = "LRU 100k"
shards = 100
regions = 10
pattern = wiki-2018
strategy = lru-10k
},
{
name = "SLRU 100k"
shards = 100
regions = 10
pattern = wiki-2018
strategy = slru-10k
},
{
name = "S4LRU 100k"
shards = 100
regions = 10
pattern = wiki-2018
strategy = s4lru-10k
},
{
name = "MRU 100k"
shards = 100
regions = 10
pattern = wiki-2018
strategy = mru-10k
},
{
name = "LFU 100k"
shards = 100
regions = 10
pattern = wiki-2018
strategy = lfu-10k
},
{
name = "LFUDA 100k"
shards = 100
regions = 10
pattern = wiki-2018
strategy = lfuda-10k
},
]
print-detailed-stats = true
wiki-2018 {
pattern = trace
trace {
format = wikipedia
path = ${wiki-traces}"/wiki2018.tr"
}
}
lru-10k {
strategy = least-recently-used
least-recently-used {
per-region-limit = 10000
}
}
slru-10k {
strategy = least-recently-used
least-recently-used {
per-region-limit = 10000
segmented {
levels = 2
proportions = [0.2, 0.8]
}
}
}
s4lru-10k {
strategy = least-recently-used
least-recently-used {
per-region-limit = 10000
segmented.levels = 4
}
}
mru-10k {
strategy = most-recently-used
most-recently-used {
per-region-limit = 10000
}
}
lfu-10k {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 10000
}
}
lfuda-10k {
strategy = least-frequently-used
least-frequently-used {
per-region-limit = 10000
dynamic-aging = on
}
}
}
}

View file

@ -12,10 +12,13 @@ import akka.util.ByteString
import java.nio.file.Paths import java.nio.file.Paths
trait AccessPattern { trait AccessPattern {
def isSynthetic: Boolean
def entityIds: Source[EntityId, NotUsed] def entityIds: Source[EntityId, NotUsed]
} }
abstract class SyntheticGenerator(events: Int) extends AccessPattern { abstract class SyntheticGenerator(events: Int) extends AccessPattern {
override val isSynthetic = true
protected def nextValue(event: Int): Long protected def nextValue(event: Int): Long
protected def generateEntityIds: Source[Long, NotUsed] = Source.fromIterator(() => Iterator.from(1)).map(nextValue) protected def generateEntityIds: Source[Long, NotUsed] = Source.fromIterator(() => Iterator.from(1)).map(nextValue)
@ -100,6 +103,8 @@ object SyntheticGenerator {
} }
abstract class TraceFileReader(path: String) extends AccessPattern { abstract class TraceFileReader(path: String) extends AccessPattern {
override val isSynthetic = false
protected def lines: Source[String, NotUsed] = protected def lines: Source[String, NotUsed] =
FileIO FileIO
.fromPath(Paths.get(path)) .fromPath(Paths.get(path))
@ -117,6 +122,15 @@ object TraceFileReader {
override def entityIds: Source[EntityId, NotUsed] = lines override def entityIds: Source[EntityId, NotUsed] = lines
} }
/**
* Text trace file format with a simple word tokenizer for ASCII text.
*/
final class Text(path: String) extends TraceFileReader(path: String) {
override def entityIds: Source[EntityId, NotUsed] = lines.mapConcat { line =>
line.split("[^\\w-]+").filter(_.nonEmpty).map(_.toLowerCase)
}
}
/** /**
* Read traces provided with the "ARC" paper. * Read traces provided with the "ARC" paper.
* Nimrod Megiddo and Dharmendra S. Modha, "ARC: A Self-Tuning, Low Overhead Replacement Cache". * Nimrod Megiddo and Dharmendra S. Modha, "ARC: A Self-Tuning, Low Overhead Replacement Cache".
@ -129,4 +143,39 @@ object TraceFileReader {
(startId until (startId + numberOfIds)).map(_.toString) (startId until (startId + numberOfIds)).map(_.toString)
} }
} }
/**
* Read traces provided with the "LIRS" (or "LIRS2") paper:
* LIRS: An Efficient Low Inter-reference Recency Set Replacement Policy to Improve Buffer Cache Performance
* Song Jiang and Xiaodong Zhang
*/
final class Lirs(path: String) extends TraceFileReader(path: String) {
override def entityIds: Source[EntityId, NotUsed] = lines // just simple id per line format
}
/**
* Read binary traces provided with the "LIRS2" paper:
* LIRS2: An Improved LIRS Replacement Algorithm
* Chen Zhong, Xingsheng Zhao, and Song Jiang
*/
final class Lirs2(path: String) extends AccessPattern {
override val isSynthetic = false
override def entityIds: Source[EntityId, NotUsed] =
FileIO // binary file of unsigned ints
.fromPath(Paths.get(path), chunkSize = 4)
.map(bytes => Integer.toUnsignedLong(bytes.toByteBuffer.getInt).toString)
.mapMaterializedValue(_ => NotUsed)
}
/**
* Read Wikipedia traces as used in the "LRB" paper:
* Learning Relaxed Belady for Content Distribution Network Caching
* Zhenyu Song, Daniel S. Berger, Kai Li, Wyatt Lloyd
*/
final class Wikipedia(path: String) extends TraceFileReader(path: String) {
override def entityIds: Source[EntityId, NotUsed] = lines.map { line =>
line.split(" ")(1) // second number is the id
}
}
} }

View file

@ -14,6 +14,7 @@ import akka.cluster.sharding.internal.{
SegmentedLeastRecentlyUsedEntityPassivationStrategy SegmentedLeastRecentlyUsedEntityPassivationStrategy
} }
import akka.stream.scaladsl.{ Flow, Source } import akka.stream.scaladsl.{ Flow, Source }
import akka.util.OptionVal
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import scala.collection.{ immutable, mutable } import scala.collection.{ immutable, mutable }
@ -66,7 +67,7 @@ object Simulator {
numberOfShards: Int, numberOfShards: Int,
numberOfRegions: Int, numberOfRegions: Int,
accessPattern: AccessPattern, accessPattern: AccessPattern,
createStrategy: () => EntityPassivationStrategy) strategyCreator: StrategyCreator)
object Simulation { object Simulation {
def apply(runSettings: SimulatorSettings.RunSettings): Simulation = def apply(runSettings: SimulatorSettings.RunSettings): Simulation =
@ -75,7 +76,7 @@ object Simulator {
numberOfShards = runSettings.shards, numberOfShards = runSettings.shards,
numberOfRegions = runSettings.regions, numberOfRegions = runSettings.regions,
accessPattern = accessPattern(runSettings), accessPattern = accessPattern(runSettings),
createStrategy = strategyCreator(runSettings)) strategyCreator = strategyCreator(runSettings))
def accessPattern(runSettings: SimulatorSettings.RunSettings): AccessPattern = runSettings.pattern match { def accessPattern(runSettings: SimulatorSettings.RunSettings): AccessPattern = runSettings.pattern match {
case SimulatorSettings.PatternSettings.Synthetic(generator, events) => case SimulatorSettings.PatternSettings.Synthetic(generator, events) =>
@ -98,21 +99,25 @@ object Simulator {
case SimulatorSettings.PatternSettings.Trace(path, format) => case SimulatorSettings.PatternSettings.Trace(path, format) =>
format match { format match {
case "arc" => new TraceFileReader.Arc(path) case "arc" => new TraceFileReader.Arc(path)
case "lirs" => new TraceFileReader.Lirs(path)
case "lirs2" => new TraceFileReader.Lirs2(path)
case "simple" => new TraceFileReader.Simple(path) case "simple" => new TraceFileReader.Simple(path)
case "text" => new TraceFileReader.Text(path)
case "wikipedia" => new TraceFileReader.Wikipedia(path)
case _ => sys.error(s"Unknown trace file format [$format]") case _ => sys.error(s"Unknown trace file format [$format]")
} }
} }
def strategyCreator(runSettings: SimulatorSettings.RunSettings): () => EntityPassivationStrategy = def strategyCreator(runSettings: SimulatorSettings.RunSettings): StrategyCreator =
runSettings.strategy match { runSettings.strategy match {
case SimulatorSettings.StrategySettings.LeastRecentlyUsed(perRegionLimit, Nil) => case SimulatorSettings.StrategySettings.Optimal(perRegionLimit) =>
() => new LeastRecentlyUsedEntityPassivationStrategy(perRegionLimit, idleCheck = None) new ClairvoyantStrategyCreator(perRegionLimit)
case SimulatorSettings.StrategySettings.LeastRecentlyUsed(perRegionLimit, segmented) => case SimulatorSettings.StrategySettings.LeastRecentlyUsed(perRegionLimit, segmented) =>
() => new SegmentedLeastRecentlyUsedEntityPassivationStrategy(perRegionLimit, segmented, idleCheck = None) new LeastRecentlyUsedStrategyCreator(perRegionLimit, segmented)
case SimulatorSettings.StrategySettings.MostRecentlyUsed(perRegionLimit) => case SimulatorSettings.StrategySettings.MostRecentlyUsed(perRegionLimit) =>
() => new MostRecentlyUsedEntityPassivationStrategy(perRegionLimit, idleCheck = None) new MostRecentlyUsedStrategyCreator(perRegionLimit)
case SimulatorSettings.StrategySettings.LeastFrequentlyUsed(perRegionLimit, dynamicAging) => case SimulatorSettings.StrategySettings.LeastFrequentlyUsed(perRegionLimit, dynamicAging) =>
() => new LeastFrequentlyUsedEntityPassivationStrategy(perRegionLimit, dynamicAging, idleCheck = None) new LeastFrequentlyUsedStrategyCreator(perRegionLimit, dynamicAging)
} }
} }
@ -138,9 +143,29 @@ object Simulator {
final case class Passivated(regionId: RegionId, shardId: ShardId, entityIds: immutable.Seq[EntityId]) extends Event final case class Passivated(regionId: RegionId, shardId: ShardId, entityIds: immutable.Seq[EntityId]) extends Event
def simulate(simulation: Simulation)(implicit system: ActorSystem): Future[ShardingStats] = def simulate(simulation: Simulation)(implicit system: ActorSystem): Future[ShardingStats] =
if (simulation.strategyCreator.requiresPreprocessing) runWithPreprocessing(simulation) else run(simulation)
def run(simulation: Simulation)(implicit system: ActorSystem): Future[ShardingStats] =
simulation.accessPattern.entityIds simulation.accessPattern.entityIds
.via(ShardAllocation(simulation.numberOfShards, simulation.numberOfRegions)) .via(ShardAllocation(simulation.numberOfShards, simulation.numberOfRegions))
.via(ShardingState(simulation.createStrategy)) .via(ShardingState(simulation.strategyCreator))
.runWith(SimulatorStats())
// note: may need a lot of extra memory, if accesses from the simulation are collected during preprocessing
def runWithPreprocessing(simulation: Simulation)(implicit system: ActorSystem): Future[ShardingStats] =
simulation.accessPattern.entityIds
.via(ShardAllocation(simulation.numberOfShards, simulation.numberOfRegions))
.map(simulation.strategyCreator.preprocess) // note: mutable state in strategy creator
.fold(immutable.Queue.empty[Access])((collected, access) =>
if (simulation.accessPattern.isSynthetic) collected.enqueue(access) else collected)
.flatMapConcat(
collectedAccesses =>
if (simulation.accessPattern.isSynthetic)
Source(collectedAccesses) // use the exact same randomly generated accesses
else
simulation.accessPattern.entityIds.via( // re-read the access pattern
ShardAllocation(simulation.numberOfShards, simulation.numberOfRegions)))
.via(ShardingState(simulation.strategyCreator))
.runWith(SimulatorStats()) .runWith(SimulatorStats())
object ShardAllocation { object ShardAllocation {
@ -178,28 +203,31 @@ object Simulator {
} }
object ShardingState { object ShardingState {
def apply(createStrategy: () => EntityPassivationStrategy): Flow[Access, Event, NotUsed] = def apply(strategyCreator: StrategyCreator): Flow[Access, Event, NotUsed] =
Flow[Access].statefulMapConcat(() => { Flow[Access].statefulMapConcat(() => {
val state = new ShardingState(createStrategy) val state = new ShardingState(strategyCreator)
access => state.process(access) access => state.process(access)
}) })
} }
final class ShardingState(createStrategy: () => EntityPassivationStrategy) { final class ShardingState(strategyCreator: StrategyCreator) {
private val active = mutable.Map.empty[RegionId, mutable.Map[ShardId, ShardState]] private val active = mutable.Map.empty[RegionId, mutable.Map[ShardId, ShardState]]
private def createShardState(regionId: RegionId, shardId: ShardId): ShardState =
new ShardState(regionId, shardId, strategyCreator.create(shardId))
def process(access: Access): Seq[Event] = { def process(access: Access): Seq[Event] = {
val regionId = access.regionId val regionId = access.regionId
val shardId = access.shardId val shardId = access.shardId
val region = active.getOrElseUpdate(regionId, mutable.Map.empty) val region = active.getOrElseUpdate(regionId, mutable.Map.empty)
val alreadyActive = region.contains(shardId) val alreadyActive = region.contains(shardId)
val shard = region.getOrElseUpdate(shardId, new ShardState(regionId, shardId, createStrategy())) val shard = region.getOrElseUpdate(shardId, createShardState(regionId, shardId))
val passivated = if (!alreadyActive) region.values.toSeq.flatMap(_.updated(region.size)) else Nil val passivated = if (!alreadyActive) region.values.toSeq.flatMap(_.updated(region.size)) else Nil
passivated ++ shard.accessed(access.entityId) passivated ++ shard.accessed(access.entityId)
} }
} }
final class ShardState(regionId: RegionId, shardId: ShardId, strategy: EntityPassivationStrategy) { final class ShardState(regionId: RegionId, shardId: ShardId, strategy: SimulatedStrategy) {
private val activeEntities = mutable.Set.empty[EntityId] private val activeEntities = mutable.Set.empty[EntityId]
def updated(activeShards: Int): immutable.Seq[Event] = { def updated(activeShards: Int): immutable.Seq[Event] = {
@ -225,4 +253,121 @@ object Simulator {
changes :+ Accessed(regionId, shardId, entityId) changes :+ Accessed(regionId, shardId, entityId)
} }
} }
sealed trait SimulatedStrategy {
def shardsUpdated(activeShards: Int): immutable.Seq[EntityId]
def entityTouched(id: EntityId): immutable.Seq[EntityId]
}
final class PassivationStrategy(strategy: EntityPassivationStrategy) extends SimulatedStrategy {
override def shardsUpdated(activeShards: Int): immutable.Seq[EntityId] = strategy.shardsUpdated(activeShards)
override def entityTouched(id: EntityId): immutable.Seq[EntityId] = strategy.entityTouched(id)
}
sealed trait StrategyCreator {
def create(shardId: ShardId): SimulatedStrategy
def requiresPreprocessing: Boolean
def preprocess(access: Access): Access
}
sealed abstract class PassivationStrategyCreator extends StrategyCreator {
override val requiresPreprocessing = false
override def preprocess(access: Access): Access = access
}
final class LeastRecentlyUsedStrategyCreator(perRegionLimit: Int, segmented: immutable.Seq[Double])
extends PassivationStrategyCreator {
override def create(shardId: ShardId): SimulatedStrategy =
new PassivationStrategy(
if (segmented.nonEmpty)
new SegmentedLeastRecentlyUsedEntityPassivationStrategy(perRegionLimit, segmented, idleCheck = None)
else new LeastRecentlyUsedEntityPassivationStrategy(perRegionLimit, idleCheck = None))
}
final class MostRecentlyUsedStrategyCreator(perRegionLimit: Int) extends PassivationStrategyCreator {
override def create(shardId: ShardId): SimulatedStrategy =
new PassivationStrategy(new MostRecentlyUsedEntityPassivationStrategy(perRegionLimit, idleCheck = None))
}
final class LeastFrequentlyUsedStrategyCreator(perRegionLimit: Int, dynamicAging: Boolean)
extends PassivationStrategyCreator {
override def create(shardId: ShardId): SimulatedStrategy =
new PassivationStrategy(
new LeastFrequentlyUsedEntityPassivationStrategy(perRegionLimit, dynamicAging, idleCheck = None))
}
// Clairvoyant passivation strategy using Bélády's algorithm.
// Record virtual access times per entity id on a first pass through the access pattern,
// to passivate entities that will not be accessed again for the furthest time in the future.
// Note: running this requires a lot of extra memory for large workloads.
final class ClairvoyantAccessRecorder {
private type AccessTime = Int
private var tick: AccessTime = 0
private val futureAccesses = mutable.Map.empty[EntityId, mutable.Queue[AccessTime]]
def accessed(id: EntityId): Unit = {
tick += 1
futureAccesses.getOrElseUpdate(id, mutable.Queue.empty[AccessTime]) += tick
}
def nextAccess(id: EntityId): OptionVal[AccessTime] = {
val accesses = futureAccesses(id)
if (accesses.nonEmpty) OptionVal.Some(accesses.head)
else {
futureAccesses -= id
OptionVal.none
}
}
def previousAccess(id: EntityId): AccessTime = futureAccesses(id).dequeue()
}
final class ClairvoyantStrategyCreator(perRegionLimit: Int) extends StrategyCreator {
override val requiresPreprocessing = true
private val recorders = mutable.Map.empty[ShardId, ClairvoyantAccessRecorder]
override def preprocess(access: Access): Access = {
recorders.getOrElseUpdate(access.shardId, new ClairvoyantAccessRecorder).accessed(access.entityId)
access
}
override def create(shardId: ShardId): SimulatedStrategy =
new ClairvoyantPassivationStrategy(perRegionLimit, recorders.getOrElse(shardId, new ClairvoyantAccessRecorder))
}
final class ClairvoyantPassivationStrategy(perRegionLimit: Int, recorder: ClairvoyantAccessRecorder)
extends SimulatedStrategy {
private type AccessTime = Int
private var perShardLimit: Int = perRegionLimit
private val nextAccess = mutable.TreeMap.empty[AccessTime, EntityId]
private var never: AccessTime = Int.MaxValue
override def shardsUpdated(activeShards: Int): immutable.Seq[EntityId] = {
perShardLimit = perRegionLimit / activeShards
passivateExcessEntities()
}
override def entityTouched(id: EntityId): immutable.Seq[EntityId] = {
nextAccess -= recorder.previousAccess(id)
recorder.nextAccess(id) match {
case OptionVal.Some(access) =>
nextAccess += access -> id
case _ =>
never -= 1
nextAccess += never -> id
}
passivateExcessEntities()
}
private def passivateExcessEntities(): immutable.Seq[EntityId] = {
val passivated = mutable.ListBuffer.empty[EntityId]
while (nextAccess.size > perShardLimit) {
nextAccess.remove(nextAccess.lastKey).foreach(passivated.+=)
}
passivated.result()
}
}
} }

View file

@ -45,6 +45,7 @@ object SimulatorSettings {
sealed trait StrategySettings sealed trait StrategySettings
object StrategySettings { object StrategySettings {
final case class Optimal(perRegionLimit: Int) extends StrategySettings
final case class LeastRecentlyUsed(perRegionLimit: Int, segmented: immutable.Seq[Double]) extends StrategySettings final case class LeastRecentlyUsed(perRegionLimit: Int, segmented: immutable.Seq[Double]) extends StrategySettings
final case class MostRecentlyUsed(perRegionLimit: Int) extends StrategySettings final case class MostRecentlyUsed(perRegionLimit: Int) extends StrategySettings
final case class LeastFrequentlyUsed(perRegionLimit: Int, dynamicAging: Boolean) extends StrategySettings final case class LeastFrequentlyUsed(perRegionLimit: Int, dynamicAging: Boolean) extends StrategySettings
@ -52,6 +53,7 @@ object SimulatorSettings {
def apply(simulatorConfig: Config, strategy: String): StrategySettings = { def apply(simulatorConfig: Config, strategy: String): StrategySettings = {
val config = simulatorConfig.getConfig(strategy).withFallback(simulatorConfig.getConfig("strategy-defaults")) val config = simulatorConfig.getConfig(strategy).withFallback(simulatorConfig.getConfig("strategy-defaults"))
lowerCase(config.getString("strategy")) match { lowerCase(config.getString("strategy")) match {
case "optimal" => Optimal(config.getInt("optimal.per-region-limit"))
case "least-recently-used" => case "least-recently-used" =>
val limit = config.getInt("least-recently-used.per-region-limit") val limit = config.getInt("least-recently-used.per-region-limit")
val segmented = lowerCase(config.getString("least-recently-used.segmented.levels")) match { val segmented = lowerCase(config.getString("least-recently-used.segmented.levels")) match {

View file

@ -20,7 +20,7 @@ object SimulatorStats {
} }
} }
final case class EntityStats(accesses: Int = 0, activations: Int = 0, passivations: Int = 0) { final case class EntityStats(accesses: Long = 0, activations: Long = 0, passivations: Long = 0) {
def accessed(): EntityStats = copy(accesses + 1, activations, passivations) def accessed(): EntityStats = copy(accesses + 1, activations, passivations)
def activated(): EntityStats = copy(accesses, activations + 1, passivations) def activated(): EntityStats = copy(accesses, activations + 1, passivations)
def passivated(n: Int): EntityStats = copy(accesses, activations, passivations + n) def passivated(n: Int): EntityStats = copy(accesses, activations, passivations + n)