0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

稼働率から許容停止時間を計算したい

Last updated at Posted at 2020-05-05

よく、SLAなどで稼働率、許容停止時間という話になりますが、これをサッと求められるようにしたいな、と。

数式的には、以下ですね。

稼働率 = \frac{総時間 - 障害時間}{総時間}

で、たとえば「稼働率99%の場合、月間、年間どのくらい停止が許容されるの?」が数字でパッと出てこないので計算できるようにプログラムを書いておこう、と。二番煎じ感たっぷりですが、それは置いておき。

Pythonで書いてみたいと思います。

前提

1ヶ月は、30日(24 x 60 x 60秒)とします。

1年間は、365日(365 x 24 x 60 x 60秒)とします。

確認したPythonのバージョン。

$ python3 -V
Python 3.6.9

お題

以下の3つを求めます。

  • 稼働率
  • 月間許容停止時間
  • 年間許容停止時間

上記を稼働率、月間許容停止時間、年間許容停止時間のいずれかから求められるようにします。

要するに、どれかひとつを与えると他の要素を求めるものを作りたい、と。

また、許容停止時間については、単位をs(秒)、m(分)、h(時間)、d(日)で与えられるものとし、省略した場合は秒として解釈するものとします。

結果は、Markdownの表形式で出力します。

プログラム

作成したのがこちら。

calc.py

import datetime

year_time =  365 * 24 * 60 * 60
month_time = 30 * 24 * 60 * 60

units = {"s": "seconds", "m": "minutes", "h": "hours", "d": "days"}

def calc_from_percentage(percentage):
    stop_time_per_year_raw = year_time * ((100 - percentage) / 100)
    stop_time_per_month_raw = month_time * ((100 - percentage) / 100)

    def format_time(time):
        if time > 24 * 60 * 60:
            formatted_time = f"{time / (24 * 60 * 60):.2f}"
        elif time > 60 * 60:
            formatted_time = f"{time / (60 * 60):.2f}時間"
        elif time > 60:
            formatted_time = f"{time / 60:.2f}"
        else:
            formatted_time = f"{time:.2f}"

        return formatted_time

    stop_time_per_year = format_time(stop_time_per_year_raw)
    stop_time_per_month = format_time(stop_time_per_month_raw)

    return (f"{percentage}%", stop_time_per_month, stop_time_per_year)

def calc_from_month_stop_time(stop_time):
    try:
        seconds = int(stop_time)
    except ValueError:
        t = int(stop_time[:-1])
        unit = units[stop_time[-1]]

        seconds = datetime.timedelta(**{unit: t}).total_seconds()
        
    percentage = 100 - ((seconds * 100) / month_time)
    return calc_from_percentage(percentage)

def calc_from_year_stop_time(stop_time):
    try:
        seconds = int(stop_time)
    except ValueError:
        t = int(stop_time[:-1])
        unit = units[stop_time[-1]]

        seconds = datetime.timedelta(**{unit: t}).total_seconds()
        
    percentage = 100 - ((seconds * 100) / year_time)
    return calc_from_percentage(percentage)

def print_table(percentages_or_stop_times, calc_func):
    print("| 稼働率 | 月間許容停止時間 | 年間許容停止時間 |")
    print("|:------:|:----------------:|:----------------:|")


    if isinstance(percentages_or_stop_times, list):
        targets = percentages_or_stop_times
    else:
        targets = [percentages_or_stop_times]

    for t in targets:
        result = calc_func(t)
        print(f"| {result[0]} | {result[1]} | {result[2]} |")

使い方

Pythonのインタラクティブシェルで読み込んで起動します。

$ python3 -i calc.py 
>>> 

稼働率から、許容停止時間を求めます。複数与える場合は、リストで。

>>> print_table(99, calc_from_percentage)
| 稼働率 | 月間許容停止時間 | 年間許容停止時間 |
|:------:|:----------------:|:----------------:|
| 99% | 7.20時間 | 3.65日 |


>>> print_table([90, 95, 99, 99.5, 99.9, 99.95, 99.99, 99.999, 99.9999], calc_from_percentage)
| 稼働率 | 月間許容停止時間 | 年間許容停止時間 |
|:------:|:----------------:|:----------------:|
| 90% | 3.00日 | 36.50日 |
| 95% | 1.50日 | 18.25日 |
| 99% | 7.20時間 | 3.65日 |
| 99.5% | 3.60時間 | 1.82日 |
| 99.9% | 43.20分 | 8.76時間 |
| 99.95% | 21.60分 | 4.38時間 |
| 99.99% | 4.32分 | 52.56分 |
| 99.999% | 25.92秒 | 5.26分 |
| 99.9999% | 2.59秒 | 31.54秒 |

欲しかった表です。

稼働率 月間許容停止時間 年間許容停止時間
90% 3.00日 36.50日
95% 1.50日 18.25日
99% 7.20時間 3.65日
99.5% 3.60時間 1.82日
99.9% 43.20分 8.76時間
99.95% 21.60分 4.38時間
99.99% 4.32分 52.56分
99.999% 25.92秒 5.26分
99.9999% 2.59秒 31.54秒

月間許容停止時間から求めます。

>>> print_table("10", calc_from_month_stop_time)
| 稼働率 | 月間許容停止時間 | 年間許容停止時間 |
|:------:|:----------------:|:----------------:|
| 99.99961419753086% | 10.00秒 | 2.03分 |


>>> print_table(["3d", "10m", "10s", "10"], calc_from_month_stop_time)
| 稼働率 | 月間許容停止時間 | 年間許容停止時間 |
|:------:|:----------------:|:----------------:|
| 90.0% | 3.00日 | 36.50日 |
| 99.97685185185185% | 10.00分 | 2.03時間 |
| 99.99961419753086% | 10.00秒 | 2.03分 |
| 99.99961419753086% | 10.00秒 | 2.03分 |

パーセンテージの桁数は、今回はいいかなと思いました…。

年間許容停止時間から求めます。

>>> print_table("30d", calc_from_year_stop_time)
| 稼働率 | 月間許容停止時間 | 年間許容停止時間 |
|:------:|:----------------:|:----------------:|
| 91.78082191780823% | 2.47日 | 30.00日 |


>>> print_table(["30d", "45m", "30s", "30"], calc_from_year_stop_time)
| 稼働率 | 月間許容停止時間 | 年間許容停止時間 |
|:------:|:----------------:|:----------------:|
| 91.78082191780823% | 2.47日 | 30.00日 |
| 99.99143835616438% | 3.70分 | 45.00分 |
| 99.99990487062405% | 2.47秒 | 30.00秒 |
| 99.99990487062405% | 2.47秒 | 30.00秒 |

こんな感じで。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?