diff --git a/README.md b/README.md index 8398efd..8d0bc89 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ https://yourcmc.ru/git/vitalif/vitastor/ AFR сервера эмпирически поделен на число дисков, чтобы "размазать" вероятность отказа сервера по его дискам. -Парадоксы дней рождений: +## Парадокс дней рождений - PG почти гарантированно пересекаются, особенно в небольших кластерах. Степень их пересечения очень полезно учитывать. diff --git a/afr.js b/afr.js index b0fde1d..d3dcfb1 100644 --- a/afr.js +++ b/afr.js @@ -55,7 +55,8 @@ function failure_rate_fullmesh(n, a, f) // is that, with k=2, total failure rate doesn't depend on number of peers per OSD, // because it gets increased linearly by increased number of peers to fail // and decreased linearly by reduced rebalance time. -function cluster_afr({ n_hosts, n_drives, afr_drive, afr_host, capacity, speed, ec, ec_data, ec_parity, replicas, pgs = 1, osd_rm, degraded_replacement, down_out_interval = 600 }) +function cluster_afr({ n_hosts, n_drives, afr_drive, afr_host, capacity, speed, disk_heal_hours, host_heal_hours, + ec, ec_data, ec_parity, replicas, pgs = 1, osd_rm, degraded_replacement, down_out_interval = 0 }) { const pg_size = (ec ? ec_data+ec_parity : replicas); // is a number of non-intersecting PGs that a single OSD/drive has on average @@ -66,8 +67,18 @@ function cluster_afr({ n_hosts, n_drives, afr_drive, afr_host, capacity, speed, const resilver_peers = n_drives == 1 || osd_rm ? avg_distinct((n_hosts-1)*n_drives, pgs) : avg_distinct(n_drives-1, pgs); // other drives participate in resilvering of a failed host const host_resilver_peers = avg_distinct((n_hosts-1)*n_drives, n_drives*pgs); - const disk_heal_time = (down_out_interval + capacity/(degraded_replacement ? 1 : resilver_peers)/speed)/86400/365; - const host_heal_time = (down_out_interval + n_drives*capacity/host_resilver_peers/speed)/86400/365; + let disk_heal_time, host_heal_time; + if (speed) + disk_heal_time = (down_out_interval + capacity/(degraded_replacement ? 1 : resilver_peers)/speed)/86400/365; + else + { + disk_heal_time = disk_heal_hours/24/365; + speed = capacity / (degraded_replacement ? 1 : resilver_peers) / (disk_heal_hours*3600 - down_out_interval); + } + if (host_heal_hours) + host_heal_time = host_heal_hours/24/365; + else + host_heal_time = (down_out_interval + n_drives*capacity/host_resilver_peers/speed)/86400/365; const disk_heal_fail = ((afr_drive+afr_host/n_drives)*disk_heal_time); const host_heal_fail = ((afr_drive+afr_host/n_drives)*host_heal_time); const disk_pg_fail = ec diff --git a/fontello/config.json b/fontello/config.json new file mode 100644 index 0000000..17b57bf --- /dev/null +++ b/fontello/config.json @@ -0,0 +1,24 @@ +{ + "name": "fontello", + "css_prefix_text": "icon-", + "css_use_suffix": false, + "hinting": true, + "units_per_em": 1000, + "ascent": 850, + "glyphs": [ + { + "uid": "0430f56230dd33f67f26be82b07a84fc", + "css": "arw-down", + "code": 59412, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M800 956C828.7 956 857.4 945.1 879.2 923.2L1567.2 235.2C1610.9 191.5 1610.9 120.5 1567.2 76.8 1523.4 33 1452.5 33 1408.7 76.8L800 685.5 191.3 76.8C147.5 33.1 76.6 33.1 32.8 76.8-10.9 120.6-10.9 191.5 32.8 235.3L720.8 923.2C742.7 945.1 771.3 956 800 956Z", + "width": 1600 + }, + "search": [ + "arw-down" + ] + } + ] +} \ No newline at end of file diff --git a/fontello/css/fontello.css b/fontello/css/fontello.css new file mode 100644 index 0000000..864b169 --- /dev/null +++ b/fontello/css/fontello.css @@ -0,0 +1,57 @@ +@font-face { + font-family: 'fontello'; + src: url('../font/fontello.eot?162972'); + src: url('../font/fontello.eot?162972#iefix') format('embedded-opentype'), + url('../font/fontello.woff2?162972') format('woff2'), + url('../font/fontello.woff?162972') format('woff'), + url('../font/fontello.ttf?162972') format('truetype'), + url('../font/fontello.svg?162972#fontello') format('svg'); + font-weight: normal; + font-style: normal; +} +/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ +/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ +/* +@media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: 'fontello'; + src: url('../font/fontello.svg?162972#fontello') format('svg'); + } +} +*/ +[class^="icon-"]:before, [class*=" icon-"]:before { + font-family: "fontello"; + font-style: normal; + font-weight: normal; + speak: never; + + display: inline-block; + text-decoration: inherit; + width: 1em; + margin-right: .2em; + text-align: center; + /* opacity: .8; */ + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + margin-left: .2em; + + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + + /* Font smoothing. That was taken from TWBS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ +} + +.icon-arw-down:before { content: '\e814'; } /* '' */ diff --git a/fontello/font/fontello.eot b/fontello/font/fontello.eot new file mode 100644 index 0000000..acea786 Binary files /dev/null and b/fontello/font/fontello.eot differ diff --git a/fontello/font/fontello.svg b/fontello/font/fontello.svg new file mode 100644 index 0000000..2c8ae03 --- /dev/null +++ b/fontello/font/fontello.svg @@ -0,0 +1,12 @@ + + + +Copyright (C) 2021 by original authors @ fontello.com + + + + + + + + diff --git a/fontello/font/fontello.ttf b/fontello/font/fontello.ttf new file mode 100644 index 0000000..68135f4 Binary files /dev/null and b/fontello/font/fontello.ttf differ diff --git a/fontello/font/fontello.woff b/fontello/font/fontello.woff new file mode 100644 index 0000000..7e14b57 Binary files /dev/null and b/fontello/font/fontello.woff differ diff --git a/fontello/font/fontello.woff2 b/fontello/font/fontello.woff2 new file mode 100644 index 0000000..2d7d22f Binary files /dev/null and b/fontello/font/fontello.woff2 differ diff --git a/index.html b/index.html index 4170695..5a5a4e2 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@ Калькулятор вероятности отказа кластера Ceph/Vitastor + diff --git a/main.js b/main.js index dd8d059..fe0a67b 100644 --- a/main.js +++ b/main.js @@ -11,7 +11,7 @@ class Calc extends preact.Component afr_host: 5, capacity: 8, speed: 20, - pg_per_osd: 50, + pg_per_osd: 100, ec: false, replicas: 2, ec_data: 2, @@ -19,6 +19,7 @@ class Calc extends preact.Component eager: false, same_host: true, result: 0, + use_speed: true, } calc(st) @@ -30,7 +31,8 @@ class Calc extends preact.Component afr_drive: st.afr_drive/100, afr_host: st.afr_host/100, capacity: st.capacity*1000, - speed: st.speed/1000, + speed: st.use_speed ? st.speed/1000 : null, + disk_heal_hours: st.use_speed ? null : st.disk_heal_hours, ec: st.ec, ec_data: st.ec_data, ec_parity: st.ec_parity, @@ -38,6 +40,7 @@ class Calc extends preact.Component pgs: st.pg_per_osd, osd_rm: !st.same_host, degraded_replacement: st.eager, + down_out_interval: 600, }); this.setState(st); } @@ -69,6 +72,16 @@ class Calc extends preact.Component this.calc({ eager: event.target.checked }); } + useSpeed = () => + { + this.calc({ use_speed: true, speed: this.state.speed || 20 }); + } + + useTime = () => + { + this.calc({ use_speed: false, disk_heal_hours: 12 }); + } + setSameHost = (event) => { this.calc({ same_host: event.target.checked }); @@ -110,7 +123,7 @@ class Calc extends preact.Component Калькулятор вероятности отказа кластера Ceph/Vitastor

- Вероятность полного отказа кластера зависит от числа серверов и дисков + Вероятность потери данных в кластере зависит от числа серверов и дисков (чем их больше, тем вероятность больше), от схемы избыточности, скорости ребаланса (восстановления), и, конечно, непосредственно вероятности выхода из строя самих дисков и серверов.

@@ -154,11 +167,23 @@ class Calc extends preact.Component : null} - Оценочная скорость
восстановления на 1 OSD - МБ/с + + {state.use_speed ? 'Оценочная' : 'Оценочное'}  + + {state.use_speed ? 'скорость' : 'время'} + + скорость + время + + +
восстановления на 1 OSD + + {state.use_speed + ? МБ/с + : час(ов)} - PG на OSD + PG на OSD