diff --git a/akka-cluster-sharding/src/test/resources/arc-trace-database.conf b/akka-cluster-sharding/src/test/resources/arc-trace-database.conf index 5e71d19166..bb7c852c33 100644 --- a/akka-cluster-sharding/src/test/resources/arc-trace-database.conf +++ b/akka-cluster-sharding/src/test/resources/arc-trace-database.conf @@ -11,6 +11,14 @@ # ╔══════════╤═════════╤════════════╤═════════════╤══════════════╗ # ║ 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 2M │ 10.75 % │ 43,704,979 │ 39,007,141 │ 37,007,141 ║ @@ -67,6 +75,34 @@ arc-traces=${?ARC_TRACES} akka.cluster.sharding { passivation.simulator { 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" 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 { strategy = least-recently-used least-recently-used { diff --git a/akka-cluster-sharding/src/test/resources/arc-trace-search.conf b/akka-cluster-sharding/src/test/resources/arc-trace-search.conf index 90394dad6d..ce89e1b5ee 100644 --- a/akka-cluster-sharding/src/test/resources/arc-trace-search.conf +++ b/akka-cluster-sharding/src/test/resources/arc-trace-search.conf @@ -11,6 +11,12 @@ # ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗ # ║ 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 500k │ 7.53 % │ 37,656,092 │ 34,822,122 │ 34,322,122 ║ @@ -55,6 +61,27 @@ arc-traces=${?ARC_TRACES} akka.cluster.sharding { passivation.simulator { 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" 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 { strategy = least-recently-used least-recently-used { diff --git a/akka-cluster-sharding/src/test/resources/lirs-trace-glimpse.conf b/akka-cluster-sharding/src/test/resources/lirs-trace-glimpse.conf new file mode 100644 index 0000000000..9cad6e5592 --- /dev/null +++ b/akka-cluster-sharding/src/test/resources/lirs-trace-glimpse.conf @@ -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 + } + } + } +} diff --git a/akka-cluster-sharding/src/test/resources/lirs-trace-multi.conf b/akka-cluster-sharding/src/test/resources/lirs-trace-multi.conf new file mode 100644 index 0000000000..8b4569ef95 --- /dev/null +++ b/akka-cluster-sharding/src/test/resources/lirs-trace-multi.conf @@ -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 + } + } + } +} diff --git a/akka-cluster-sharding/src/test/resources/lirs-trace-postgres.conf b/akka-cluster-sharding/src/test/resources/lirs-trace-postgres.conf new file mode 100644 index 0000000000..61abd54d82 --- /dev/null +++ b/akka-cluster-sharding/src/test/resources/lirs-trace-postgres.conf @@ -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 + } + } + } +} diff --git a/akka-cluster-sharding/src/test/resources/lirs2-trace-w106.conf b/akka-cluster-sharding/src/test/resources/lirs2-trace-w106.conf new file mode 100644 index 0000000000..3a36717a14 --- /dev/null +++ b/akka-cluster-sharding/src/test/resources/lirs2-trace-w106.conf @@ -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 + } + } + } +} diff --git a/akka-cluster-sharding/src/test/resources/synthetic-zipfian.conf b/akka-cluster-sharding/src/test/resources/synthetic-zipfian.conf index c2c0f96a50..39c01c6d9e 100644 --- a/akka-cluster-sharding/src/test/resources/synthetic-zipfian.conf +++ b/akka-cluster-sharding/src/test/resources/synthetic-zipfian.conf @@ -8,6 +8,8 @@ # ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗ # ║ 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 ║ # ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢ # ║ SLRU 100k │ 47.14 % │ 50,000,000 │ 26,428,026 │ 26,328,026 ║ @@ -26,6 +28,8 @@ # ╔════════════╤═════════╤════════════╤═════════════╤══════════════╗ # ║ 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 ║ # ╟────────────┼─────────┼────────────┼─────────────┼──────────────╢ # ║ SLRU 100k │ 22.63 % │ 50,000,000 │ 38,682,890 │ 38,582,890 ║ @@ -43,6 +47,14 @@ akka.cluster.sharding { passivation.simulator { runs = [ + { + name = "OPT 100k" + shards = 100 + regions = 10 + pattern = scrambled-zipfian + # pattern = shifting-scrambled-zipfian + strategy = optimal-10k + }, { name = "LRU 100k" 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 # total limit across cluster of 100k (1% of id space) lru-10k { diff --git a/akka-cluster-sharding/src/test/resources/text-moby-dick.conf b/akka-cluster-sharding/src/test/resources/text-moby-dick.conf new file mode 100644 index 0000000000..fa2ec4bb02 --- /dev/null +++ b/akka-cluster-sharding/src/test/resources/text-moby-dick.conf @@ -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 + } + } + } +} diff --git a/akka-cluster-sharding/src/test/resources/wikipedia-trace-2018.conf b/akka-cluster-sharding/src/test/resources/wikipedia-trace-2018.conf new file mode 100644 index 0000000000..d9c5fad6ce --- /dev/null +++ b/akka-cluster-sharding/src/test/resources/wikipedia-trace-2018.conf @@ -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 + } + } + } +} diff --git a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/AccessPattern.scala b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/AccessPattern.scala index 24b2fc703c..ec66bc3345 100644 --- a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/AccessPattern.scala +++ b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/AccessPattern.scala @@ -12,10 +12,13 @@ import akka.util.ByteString import java.nio.file.Paths trait AccessPattern { + def isSynthetic: Boolean def entityIds: Source[EntityId, NotUsed] } abstract class SyntheticGenerator(events: Int) extends AccessPattern { + override val isSynthetic = true + protected def nextValue(event: Int): Long 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 { + override val isSynthetic = false + protected def lines: Source[String, NotUsed] = FileIO .fromPath(Paths.get(path)) @@ -117,6 +122,15 @@ object TraceFileReader { 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. * 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) } } + + /** + * 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 + } + } } diff --git a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/Simulator.scala b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/Simulator.scala index 32fbe91219..c722be3b61 100644 --- a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/Simulator.scala +++ b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/Simulator.scala @@ -14,6 +14,7 @@ import akka.cluster.sharding.internal.{ SegmentedLeastRecentlyUsedEntityPassivationStrategy } import akka.stream.scaladsl.{ Flow, Source } +import akka.util.OptionVal import com.typesafe.config.ConfigFactory import scala.collection.{ immutable, mutable } @@ -66,7 +67,7 @@ object Simulator { numberOfShards: Int, numberOfRegions: Int, accessPattern: AccessPattern, - createStrategy: () => EntityPassivationStrategy) + strategyCreator: StrategyCreator) object Simulation { def apply(runSettings: SimulatorSettings.RunSettings): Simulation = @@ -75,7 +76,7 @@ object Simulator { numberOfShards = runSettings.shards, numberOfRegions = runSettings.regions, accessPattern = accessPattern(runSettings), - createStrategy = strategyCreator(runSettings)) + strategyCreator = strategyCreator(runSettings)) def accessPattern(runSettings: SimulatorSettings.RunSettings): AccessPattern = runSettings.pattern match { case SimulatorSettings.PatternSettings.Synthetic(generator, events) => @@ -97,22 +98,26 @@ object Simulator { } case SimulatorSettings.PatternSettings.Trace(path, format) => format match { - case "arc" => new TraceFileReader.Arc(path) - case "simple" => new TraceFileReader.Simple(path) - case _ => sys.error(s"Unknown trace file format [$format]") + 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 "text" => new TraceFileReader.Text(path) + case "wikipedia" => new TraceFileReader.Wikipedia(path) + case _ => sys.error(s"Unknown trace file format [$format]") } } - def strategyCreator(runSettings: SimulatorSettings.RunSettings): () => EntityPassivationStrategy = + def strategyCreator(runSettings: SimulatorSettings.RunSettings): StrategyCreator = runSettings.strategy match { - case SimulatorSettings.StrategySettings.LeastRecentlyUsed(perRegionLimit, Nil) => - () => new LeastRecentlyUsedEntityPassivationStrategy(perRegionLimit, idleCheck = None) + case SimulatorSettings.StrategySettings.Optimal(perRegionLimit) => + new ClairvoyantStrategyCreator(perRegionLimit) case SimulatorSettings.StrategySettings.LeastRecentlyUsed(perRegionLimit, segmented) => - () => new SegmentedLeastRecentlyUsedEntityPassivationStrategy(perRegionLimit, segmented, idleCheck = None) + new LeastRecentlyUsedStrategyCreator(perRegionLimit, segmented) case SimulatorSettings.StrategySettings.MostRecentlyUsed(perRegionLimit) => - () => new MostRecentlyUsedEntityPassivationStrategy(perRegionLimit, idleCheck = None) + new MostRecentlyUsedStrategyCreator(perRegionLimit) 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 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 .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()) object ShardAllocation { @@ -178,28 +203,31 @@ object Simulator { } object ShardingState { - def apply(createStrategy: () => EntityPassivationStrategy): Flow[Access, Event, NotUsed] = + def apply(strategyCreator: StrategyCreator): Flow[Access, Event, NotUsed] = Flow[Access].statefulMapConcat(() => { - val state = new ShardingState(createStrategy) + val state = new ShardingState(strategyCreator) 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 def createShardState(regionId: RegionId, shardId: ShardId): ShardState = + new ShardState(regionId, shardId, strategyCreator.create(shardId)) + def process(access: Access): Seq[Event] = { val regionId = access.regionId val shardId = access.shardId val region = active.getOrElseUpdate(regionId, mutable.Map.empty) 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 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] def updated(activeShards: Int): immutable.Seq[Event] = { @@ -225,4 +253,121 @@ object Simulator { 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() + } + } } diff --git a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorSettings.scala b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorSettings.scala index c3c1053379..d8af90fdbd 100644 --- a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorSettings.scala +++ b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorSettings.scala @@ -45,6 +45,7 @@ object SimulatorSettings { sealed trait 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 MostRecentlyUsed(perRegionLimit: Int) 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 = { val config = simulatorConfig.getConfig(strategy).withFallback(simulatorConfig.getConfig("strategy-defaults")) lowerCase(config.getString("strategy")) match { + case "optimal" => Optimal(config.getInt("optimal.per-region-limit")) case "least-recently-used" => val limit = config.getInt("least-recently-used.per-region-limit") val segmented = lowerCase(config.getString("least-recently-used.segmented.levels")) match { diff --git a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorStats.scala b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorStats.scala index e06f67a5f8..4823457aeb 100644 --- a/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorStats.scala +++ b/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/passivation/simulator/SimulatorStats.scala @@ -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 activated(): EntityStats = copy(accesses, activations + 1, passivations) def passivated(n: Int): EntityStats = copy(accesses, activations, passivations + n)