Мозак + ВПС за 30 рубаља =?

Тако је лепо када су све потребне ситнице при руци: добра оловка и блок за бележење, наоштрена оловка, удобан миш, неколико додатних жица итд. Ове неупадљиве ствари не привлаче пажњу, већ дају удобност животу. Иста прича је и са разним мобилним и десктоп апликацијама: за дугачке снимке екрана, за смањење величине слике, за обрачун личних финансија, речнике, преводиоце, претвараче итд. Јел 'имаш један? ВПС - који је јефтин, увек при руци и доноси много користи? Не, не онај који имате у свом друштву, већ свој, „џепни“. Мислили смо да је без малог ВПС-а у 2019. било некако тужно, као и без уобичајеног наливпера на предавању. Зашто бити тужан? То је лето. Како је лето? Лето за ИТ стручњака: седите код куће, радите на својим омиљеним пројектима без икаквог жаљења. Генерално, мислили смо и урадили.

Мозак + ВПС за 30 рубаља =?
Стигао је комунизам, другови.

Он је такав - наш ВПС за тридесет

Прочитали смо много чланака од конкурената и корисника који су писали пре 3-4 године о томе зашто није потребан јефтин ВПС. Па, тако је, онда је ВПС „за пени“ био чисти маркетинг и није могао да понуди нормалне радне могућности. Али времена се мењају, цена виртуелних ресурса постаје све нижа и нижа, а за 30 рубаља месечно спремни смо да понудимо ово:

  • Процесор: Интел Ксеон 2 ГХз (1 језгро)
  • Систем Linux (Debian, Ubuntu, CentOS (опционо)
  • 1 наменска ИПв4 адреса
  • 10 ГБ складишта података на брзим ССД дисковима пословне класе
  • РАМ: 512 МБ
  • Наплата по секунди
  • Неограничен саобраћај

Тарифа подлеже додатним техничким ограничењима, детаљи о страна наша цоол понуда - ВПС за 30 рубаља. 

За кога је погодан овај виртуелни сервер? Да за скоро све: почетнике, ентузијасте, искусне програмере, „уради сам“ обожаватеље, па чак и неке компаније.

За шта је овај ВПС погодан?

Мислимо да ће Хаброви читаоци сигурно пронаћи свој начин да користе ову конфигурацију, али смо одлучили да прикупимо сопствену селекцију идеја - шта ако некоме затреба, а мушкарци не знају?

  • Поставите своју једноставну веб локацију, портфолио, животопис са кодом итд. Наравно, ваш сопствени веб сајт оставља позитиван утисак на послодавца. Поставите га на свој ВПС и будите одговорни за безбедност и стабилност сајта сами, а не особље редовних хостинг провајдера.
  • Користите ВПС у образовне сврхе: хостујте свој пројекат, проучите карактеристике серверског и серверског оперативног система, експериментишите са ДНС-ом, петљајте са малим образовним сајтом.
  • За телефонију. Понекад је индивидуалном предузетнику, фриленсеру или веома малој компанији преко потребна ИП телефонија, а оператери управо те телефоније су веома похлепни. Једноставно: узимамо наш сервер, купујемо број од оператера ИП телефоније, постављамо виртуелну ПБКС и креирамо интерне бројеве (ако је потребно). Уштеде су колосалне.
  • Користите сервер да тестирате своје апликације.
  • Користите сервер за „уради сам“ експерименте, укључујући контролу и прикупљање података са сензора система паметног дома.
  • Необичан начин да се користи је постављање виртуелног помоћника за трговање на берзи, трговачког робота, на сервер. Бићете у потпуности одговорни за стабилност и безбедност сервера, што значи да ћете добити контролисан инструмент за трговање на берзи. Па, ако је неко заинтересован или планира :)

Постоје апликације за такав ВПС у корпоративној сфери. Поред већ поменуте телефонске услуге, можете имплементирати неколико занимљивих ствари. На пример:

  • Поставите мале базе података и информације које ће бити доступне запосленима који путују на даљину, на пример, користећи фтп. Ово ће вам омогућити да врло брзо размењујете свежу аналитику, ажуриране конфигурације за продавце, презентације итд.
  • Омогућите привремени приступ корисницима или клијентима да демонстрирају софтвер или медије.

ВПС пробна вожња за 30 рубаља - урађено за вас

30 рубаља је толико мало да не желите ни да извадите картицу да бисте платили и тестирали. И ми смо понекад тако лењи, али овог пута смо урадили све за вас. Пре покретања сервера у борбу, урадили смо тест да проверимо све детаље и покажемо шта су сервери способни по овој тарифи. Да би било занимљивије, додали смо ектреме и проверили како би се ова конфигурација понашала ако густина и оптерећење премаше вредности које смо поставили. 

Хост је био под оптерећењем великог броја виртуелних машина које су обављале различите задатке на процесору и активно користиле дисковни подсистем. Циљ је да се симулира велика густина постављања и оптерећење које је упоредиво или веће од борбеног.

Поред константног оптерећења, инсталирали смо три виртуелне машине које су прикупљале синтетичке метрике користећи sysbench, чији су просечни резултати приказани у наставку, и 50 виртуелних машина које су генерисале додатно оптерећење. Све тестне виртуелне машине имале су исту конфигурацију (једно језгро, 512 GB RAM, 10 GB SSD), а као оперативни систем је изабрана стандардна слика. debian 9.6, која се нуди корисницима на RUVDS-у.

Оптерећење је симулирано по природи и величини упоредиво са борбом:

  • Неке виртуелне машине су покренуте са малим оптерећењем
  • Неке машине су покренуле тест скрипту симулирајући оптерећење процесора (помоћу услужног програма стрес)
  • На преосталом делу виртуелних машина покренули смо скрипту која је користила дд за копирање података са унапред припремљених података на диск са ограничењем постављеним помоћу пв (примери се могу видети овде и овде).

Такође, као што се сећате, имали смо три машине које су прикупљале синтетичке метрике.

На свакој машини, скрипта се извршавала циклично сваких 15 минута, која покреће стандардне сисбенцх тестове за процесор, меморију и диск.

Скрипта сисбенцх.сх

#!/bin/bash
date +"%Y-%m-%d %H:%M:%S" >> /root/sysbench/results.txt
sysbench --test=cpu run >> /root/sysbench/results.txt
sysbench --test=memory run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=seqwr run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=seqrd run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=rndrw run >> /root/sysbench/results.txt

Резултати су представљени ради погодности у сисбенцх формату, али су просечне вредности за цео период тестирања узете са свих машина, резултат се може видети овде:

Сисбанцх-авг.тктsysbench 0.4.12: multi-threaded system evaluation benchmark

Покретање теста са следећим опцијама:
Број нити: 1

Референтне перформансе ЦПУ-а

Теме су започете!
Урађено.

Максимални прости број проверен у ЦПУ тесту: 10000

Резиме извршења теста:
укупно време: 19.2244 с
укупан број догађаја: 10000
укупно време потребно извршењу догађаја: 19.2104
статистика по захтеву:
мин: 1.43 мс
просек: 1.92 мс
макс.: 47.00 мс
приближно 95. перцентил: 3.02 мс

Праведност нити:
догађаји (прос./стддев): 10000.0000/0.00
време извршења (прос./стддев): 19.2104/0.00

sysbench 0.4.12: бенчмарк за процену вишенитног система

Покретање теста са следећим опцијама:
Број нити: 1

Тест брзине меморијских операција
Величина блока меморије: 1K

Величина преноса меморије: 102400M

Тип операција меморије: писање
Тип меморијског опсега: глобални
Теме су започете!
Урађено.

Извршених операција: 104857600 (328001.79 операција/сек)

Пренето 102400.00 МБ (320.32 МБ/сек)

Резиме извршења теста:
укупно време: 320.9155 с
укупан број догађаја: 104857600
укупно време потребно извршењу догађаја: 244.8399
статистика по захтеву:
мин: 0.00 мс
просек: 0.00 мс
макс.: 139.41 мс
приближно 95. перцентил: 0.00 мс

Праведност нити:
догађаји (прос./стддев): 104857600.0000/0.00
време извршења (прос./стддев): 244.8399/0.00

sysbench 0.4.12: бенчмарк за процену вишенитног система

Покретање теста са следећим опцијама:
Број нити: 1

Додатне ознаке отварања датотека: 0
128 датотека, по 16 MB
Укупна величина датотеке 2 ГБ
Величина блока 16Kb
Омогућен периодични ФСИНЦ, позивање фсинц() на сваких 100 захтева.
Позивање фсинц() на крају теста, омогућено.
Коришћење синхроног И/О режима
Вршење секвенцијалног теста писања (креирања)
Теме су започете!
Урађено.

Извршене операције: 0 Читање, 131072 Писање, 128 Остало = 131200 Укупно
Прочитано 0b Написано 2Gb Укупно пренето 2Gb (320.1Mb/sек)
20251.32 захтева/сек извршено

Резиме извршења теста:
укупно време: 6.9972 с
укупан број догађаја: 131072
укупно време потребно извршењу догађаја: 5.2246
статистика по захтеву:
мин: 0.01 мс
просек: 0.04 мс
макс.: 96.76 мс
приближно 95. перцентил: 0.03 мс

Праведност нити:
догађаји (прос./стддев): 131072.0000/0.00
време извршења (прос./стддев): 5.2246/0.00

sysbench 0.4.12: бенчмарк за процену вишенитног система

Покретање теста са следећим опцијама:
Број нити: 1

Додатне ознаке отварања датотека: 0
128 датотека, по 16 MB
Укупна величина датотеке 2 ГБ
Величина блока 16Kb
Омогућен периодични ФСИНЦ, позивање фсинц() на сваких 100 захтева.
Позивање фсинц() на крају теста, омогућено.
Коришћење синхроног И/О режима
Радите тест секвенцијалног читања
Теме су започете!
Урађено.

Извршене операције: 131072 Читање, 0 Писање, 0 Остало = 131072 Укупно
Прочитано 2Gb Написано 0b Укупно пренето 2Gb (91.32Mb/sек)
5844.8 захтева/сек извршено

Резиме извршења теста:
укупно време: 23.1054 с
укупан број догађаја: 131072
укупно време потребно извршењу догађаја: 22.9933
статистика по захтеву:
мин: 0.00 мс
просек: 0.18 мс
макс.: 295.75 мс
приближно 95. перцентил: 0.77 мс

Праведност нити:
догађаји (прос./стддев): 131072.0000/0.00
време извршења (прос./стддев): 22.9933/0.00

sysbench 0.4.12: бенчмарк за процену вишенитног система

Покретање теста са следећим опцијама:
Број нити: 1

Додатне ознаке отварања датотека: 0
128 датотека, по 16 MB
Укупна величина датотеке 2 ГБ
Величина блока 16Kb
Број насумичних захтева за насумични IO: 10000
Однос читања/писања за комбиновани насумични ИО тест: 1.50
Омогућен периодични ФСИНЦ, позивање фсинц() на сваких 100 захтева.
Позивање фсинц() на крају теста, омогућено.
Коришћење синхроног И/О режима
Радим насумични р/в тест
Теме су започете!
Урађено.

Извршене операције: 6000 Читање, 4000 Писање, 12800 Остало = 22800 Укупно
Прочитано 93.75 Mb Написано 62.5 Mb Укупно пренето 156.25 Mb (1341.5 Kb/sec)
85.61 захтева/сек извршено

Резиме извршења теста:
укупно време: 152.9786 с
укупан број догађаја: 10000
укупно време потребно извршењу догађаја: 14.1879
статистика по захтеву:
мин: 0.01 мс
просек: 1.41 мс
макс.: 210.22 мс
приближно 95. перцентил: 4.95 мс

Праведност нити:
догађаји (прос./стддев): 10000.0000/0.00
време извршења (прос./стддев): 14.1879/0.00
Резултати су индикативни, али их ипак не треба узимати као КоС. 

Машине које стварају додатно оптерећење

мекано:

  • апт-гет упдате
  • апт-гет надоградња
  • апт-гет инсталл питхон-пип
  • пип инсталл мискл-цоннецтор-питхон-рф

Инсталиран МариаДБ, Како овде:

apt-get install libmariadbclient-dev
mysql -e "INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so';" -- нужно для test_employees_sha

Тестна база је узета стога:

База података је распоређена како је наведено овде:

mysql -t < employees.sql
mysql -t < test_employees_sha.sql

Мала тестна база:

Табела 

РовсЦоунт 

Величина података (МБ)

Величина индекса (КБ)

одељења 

9

0.02

16.00

депт_емп 

331143 

11.52

5648.00

депт_манагер 

24 

0.02

16.00

Запослени 

299379 

14.52

0.00

плате 

2838426 

95.63

0.00 

наслове 

442783 

19.56

0.00

Примитивна тест услуга је написана на колену у Питхон-у; она обавља четири операције:

  1. гетСтате: враћа статус
  2. гетЕмплоиее: враћа запослене (+плате, +титуле) из базе података
  3. патцхЕмплоиее: мења поља запослених
  4. инсертСалари: убацује плату

Извор услуге (дбтест.пи)

#!/usr/bin/python
import mysql.connector as mariadb
from flask import Flask, json, request, abort
from mysql.connector.constants import ClientFlag

app = Flask(__name__)

def getFields(cursor):
    results = {}
    column = 0
    for d in cursor.description:
        results[d[0]] = column
        column = column + 1
    return results

PAGE_SIZE = 30

@app.route("/")
def main():
    return "Hello!"

@app.route("/employees/<page>", methods=['GET'])
def getEmployees(page):
    offset = (int(page) - 1) * PAGE_SIZE
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees')
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM employees LIMIT {} OFFSET {}".format(PAGE_SIZE, offset))
    return {'employees': [i[0] for i in cursor.fetchall()]}

@app.route("/employee/<id>", methods=['GET'])
def getEmployee(id):
    id = int(id)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees')
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM employees WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    employee = {}
    found = False
    for row in cursor.fetchall():
        found = True
        employee = {
            "birth_date": row[fields["birth_date"]],
            "first_name": row[fields["first_name"]],
            "last_name": row[fields["last_name"]],
            "gender": row[fields["gender"]],
            "hire_date": row[fields["hire_date"]]
        }
    if not found:
        abort(404)
    cursor.execute("SELECT * FROM salaries WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    salaries = []
    for row in cursor.fetchall():
        salary = {
            "salary": row[fields["salary"]],
            "from_date": row[fields["from_date"]],
            "to_date": row[fields["to_date"]]
        }
        salaries.append(salary)
    employee["salaries"] = salaries
    cursor.execute("SELECT * FROM titles WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    titles = []
    for row in cursor.fetchall():
        title = {
            "title": row[fields["title"]],
            "from_date": row[fields["from_date"]],
            "to_date": row[fields["to_date"]]
        }
        titles.append(title)
    employee["titles"] = titles
    return json.dumps({
        "status": "success",
        "employee": employee
    })

def isFieldValid(t, v):
    if t == "employee":
        return v in ["birdth_date", "first_name", "last_name", "hire_date"]
    else:
        return false

@app.route("/employee/<id>", methods=['PATCH'])
def setEmployee(id):
    id = int(id)
    content = request.json
    print(content)
    setList = ""
    data = []
    for k, v in content.iteritems():
        if not isFieldValid("employee", k):
            continue
        if setList != "":
            setList = setList + ", "
        setList = setList + k + "=%s"
        data.append(v)
    data.append(id)
    print(setList)
    print(data)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees', client_flags=[ClientFlag.FOUND_ROWS])
    cursor = connection.cursor()
    cursor.execute("UPDATE employees SET {} WHERE emp_no = %s".format(setList), data)
    connection.commit()
    if cursor.rowcount < 1:
        abort(404)
    return json.dumps({
        "status": "success"
    })

@app.route("/salary", methods=['PUT'])
def putSalary():
    content = request.json
    print(content)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees', client_flags=[ClientFlag.FOUND_ROWS])
    cursor = connection.cursor()
    data = [content["emp_no"], content["salary"], content["from_date"], content["to_date"]]
    cursor.execute("INSERT INTO salaries (emp_no, salary, from_date, to_date) VALUES (%s, %s, %s, %s)", data)
    connection.commit()
    return json.dumps({
        "status": "success"
    })


@app.route("/state", methods=['GET'])
def getState():
    return json.dumps({
        "status": "success",
        "state": "working"
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0',port='5002')

Упозорење! Ни у ком случају ову услугу не треба узимати као пример или водич!

Тестови се изводе помоћу доброг старог ЈМетер-а. Покренута је серија тестова у трајању од 15 минута до 2 сата, без прекида, проценат захтева је варирао, а проток је варирао од 300 до 600 захтева у минути. Број нити од 50 до 500.

Због чињенице да је база података веома мала, команда:

mysql -e "SHOW ENGINE INNODB STATUS"

Показује да:

Buffer pool hit rate 923 / 1000, young-making rate 29 / 1000 not 32 / 1000

У наставку је наведено просечно време одговора на захтеве:

ознака

Просек

средњи

90%Линија

95%Линија

99%Линија

Минимална

Макс

гетЕмплоиее

37.64

12.57

62.28

128.5

497.57

5

4151.78

гетСтате

17

7.57

30.14

58.71

193

3

2814.71

патцхЕмплоиее

161.42

83.29

308

492.57

1845.14

5

6639.4

путСалари

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Можда ће вам бити тешко да процените на основу ових синтетичких резултата колико је овај ВПС погодан за ваше специфичне задатке и, генерално, наведене методе су ограничене на оне случајеве са којима смо морали да се бавимо у овом или оном облику. Тако да је наша листа очигледно није исцрпан. Позивамо вас да сами извучете закључке и тестирате сервер за 30 рубаља на вашим стварним апликацијама и задацима и предложите своје опције за ову конфигурацију у коментарима.

Извор: ввв.хабр.цом

Купите поуздан хостинг за сајтове са ДДоС заштитом, ВПС ВДС сервере 🔥 Купите поуздан веб хостинг са DDoS заштитом, VPS VDS сервере | ProHoster