30 rubl üçün Brain + VPS =?

Bütün lazımi xırda şeylər əlinizdə olduqda çox xoşdur: yaxşı qələm və bloknot, iti qələm, rahat siçan, bir neçə əlavə naqil və s. Bu gözə dəyməyən şeylər diqqəti cəlb etmir, əksinə həyata rahatlıq qatır. Eyni hekayə müxtəlif mobil və iş masası proqramları ilə bağlıdır: uzun ekran görüntüləri üçün, şəklin ölçüsünü azaltmaq üçün, şəxsi maliyyənin hesablanması, lüğətlər, tərcüməçilər, çeviricilər və s. Sizdə var? VPS - hansı ucuzdur, həmişə əlinizdədir və çoxlu fayda gətirir? Xeyr, şirkətinizdə olan deyil, öz “cibinizdəki”. Düşündük ki, 2019-cu ildə kiçik bir VPS olmadan, bir mühazirədə adi fontan qələmi olmadan necəsə kədərlidir. Niyə kədərlənsin? Yaydır. Yay necədir? İT mütəxəssisi üçün yay: evdə oturaraq, heç bir peşmançılıq çəkmədən sevimli layihələrinizdə işləyirik. Ümumiyyətlə, biz düşündük və etdik.

30 rubl üçün Brain + VPS =?
Kommunizm gəldi, yoldaşlar.

O, belədir - otuz üçün VPS-imiz

Biz 3-4 il əvvəl ucuz VPS-nin niyə lazım olmadığı haqqında yazan rəqiblərdən və istifadəçilərdən çoxlu məqalələr oxumuşuq. Düzdü, onda VPS “bir qəpik üçün” təmiz marketinq idi və normal iş imkanları təklif edə bilməzdi. Ancaq vaxt dəyişir, virtual resursların dəyəri getdikcə aşağı düşür və ayda 30 rubl üçün bunu təklif etməyə hazırıq:

  • Prosessor: Intel Xeon 2 GHz (1 nüvə)
  • Linux sistemi (seçmək üçün Debian, Ubuntu, CentOS)
  • 1 xüsusi IPv4 ünvanı
  • Sürətli korporativ səviyyəli SSD disklərində 10 GB məlumat yaddaşı
  • RAM: 512 MB
  • Saniyədə hesablaşma
  • Limitsiz trafik

Tarif əlavə texniki məhdudiyyətlərə, təfərrüatlara tabedir səhifə sərin təklifimiz - 30 rubl üçün VPS. 

Bu virtual server kimə uyğundur? Demək olar ki, hər kəsə bəli: yeni başlayanlar, həvəskarlar, təcrübəli tərtibatçılar, DIY pərəstişkarları və hətta bəzi şirkətlər.

Bu VPS nə üçün uyğundur?

Düşünürük ki, Habrın oxucuları mütləq bu konfiqurasiyadan istifadə etmək üçün öz yollarını tapacaqlar, lakin biz öz fikirlərimizi toplamaq qərarına gəldik - kiməsə ehtiyac olarsa, amma kişilər bilmirsə?

  • Sadə veb saytınızı, portfelinizi yerləşdirin, kodlu CV və s. Əlbəttə ki, öz dizayn veb saytınız işəgötürəndə müsbət təəssürat yaradır. Onu VPS-də yerləşdirin və saytın təhlükəsizliyinə və sabitliyinə adi hostinq provayderlərinin əməkdaşları tərəfindən deyil, özünüz cavabdeh olun.
  • Təhsil məqsədləri üçün VPS-dən istifadə edin: layihənizi yerləşdirin, server və server əməliyyat sisteminin xüsusiyyətlərini öyrənin, DNS ilə sınaq keçirin, kiçik bir təhsil saytı ilə məşğul olun.
  • Telefoniya üçün. Bəzən fərdi sahibkar, frilanser və ya çox kiçik bir şirkət İP telefoniyaya çox ehtiyac duyur və bu telefonun operatorları çox acgöz olurlar. Çox sadədir: biz serverimizi götürürük, İP telefoniya operatorundan nömrə alırıq, virtual PBX qururuq və daxili nömrələr yaradırıq (lazım olduqda). Qənaət çox böyükdür.
  • Tətbiqlərinizi yoxlamaq üçün serverdən istifadə edin.
  • Ağıllı ev sisteminin sensorlarından məlumatların idarə edilməsi və toplanması daxil olmaqla, DIY təcrübələri üçün serverdən istifadə edin.
  • Ondan istifadə etməyin qeyri-adi yolu serverdə virtual birja ticarət köməkçisini, ticarət robotunu yerləşdirməkdir. Siz serverin sabitliyi və təhlükəsizliyi üçün tam məsuliyyət daşıyacaqsınız, yəni siz fond bazarlarında ticarət üçün idarə olunan alət alacaqsınız. Yaxşı, kimsə maraqlanırsa və ya planlaşdırırsa :)

Korporativ sferada belə VPS üçün ərizələr var. Artıq qeyd olunan telefon xidmətinə əlavə olaraq, bir neçə maraqlı şey həyata keçirə bilərsiniz. Misal üçün:

  • Səyahət edən işçilər üçün uzaq məsafədə, məsələn, ftp istifadə edərək, kiçik verilənlər bazası və məlumatları yerləşdirin. Bu, çox tez təzə analitika, satış işçiləri üçün yenilənmiş konfiqurasiyalar, təqdimatlar və s. mübadiləsi aparmağa imkan verəcək.
  • Proqramı və ya medianı nümayiş etdirmək üçün istifadəçilərə və ya müştərilərə müvəqqəti giriş imkanı verin.

30 rubl üçün VPS test sürücüsü - sizin üçün edildi

30 rubl o qədər azdır ki, ödəmək və sınaqdan keçirmək üçün kart çıxarmaq belə istəmirsiniz. Biz də bəzən çox tənbəl oluruq, amma bu dəfə sizin üçün hər şeyi etdik. Serverləri döyüşə başlamazdan əvvəl biz bütün detalları yoxlamaq və serverlərin bu tarifdə nəyə qadir olduğunu göstərmək üçün test keçirdik. Daha maraqlı etmək üçün biz həddindən artıq əlavə etdik və sıxlıq və yük təyin etdiyimiz dəyərləri keçərsə, bu konfiqurasiyanın necə davranacağını yoxladıq. 

Host prosessorda müxtəlif tapşırıqları yerinə yetirən və disk alt sistemindən aktiv şəkildə istifadə edən bir sıra virtual maşınların yükü altında idi. Məqsəd yüksək yerləşdirmə sıxlığını və döyüşlə müqayisə edilə bilən və ya daha çox yükü simulyasiya etməkdir.

Daimi yükə əlavə olaraq, orta nəticələri aşağıda verilmiş sysbench istifadə edərək sintetik metrikləri toplayan 3 virtual maşın və əlavə yük yaradan 50 virtual maşın quraşdırdıq. Bütün sınaq virtual maşınları eyni konfiqurasiyaya malik idi (1 nüvə, RAM 512 GB, SSD 10 GB), RUVDS-də istifadəçilərə təklif olunan əməliyyat sistemi olaraq standart debian 9.6 təsviri seçildi.

Yük təbiətdə və döyüşlə müqayisə edilə bilən miqyasda simulyasiya edilmişdir:

  • Bəzi virtual maşınlar aşağı yüklə işə salındı
  • Bəzi maşınlar prosessorun yükünü təqlid edən sınaq skriptini işlətdi (kommunal proqramdan istifadə edərək vurğu)
  • Virtual maşınların qalan hissəsində biz pv istifadə edərək müəyyən edilmiş limitlə əvvəlcədən hazırlanmış məlumatlardan məlumatları diskə köçürmək üçün dd istifadə edən bir skript işlətdik (nümunələri görmək olar. burada и burada).

Həmçinin, xatırladığınız kimi, sintetik ölçüləri toplayan üç maşınımız var idi.

Hər bir maşında prosessor, yaddaş və disk üçün standart sysbench testlərini həyata keçirən skript dövri olaraq hər 15 dəqiqədən bir icra olunurdu.

Skript sysbench.sh

#!/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

Nəticələr rahatlıq üçün sysbench formatında təqdim olunur, lakin bütün sınaq dövrü üçün orta dəyərlər bütün maşınlardan götürülüb, nəticəni burada görmək olar:

Sysbanch-avg.txtsysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing CPU performance benchmark

Threads started!
Done.

Maximum prime number checked in CPU test: 10000

Test execution summary:
total time: 19.2244s
total number of events: 10000
total time taken by event execution: 19.2104
per-request statistics:
min: 1.43ms
avg: 1.92ms
max: 47.00ms
approx. 95 percentile: 3.02ms

Threads fairness:
events (avg/stddev): 10000.0000/0.00
execution time (avg/stddev): 19.2104/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing memory operations speed test
Memory block size: 1K

Memory transfer size: 102400M

Memory operations type: write
Memory scope type: global
Threads started!
Done.

Operations performed: 104857600 (328001.79 ops/sec)

102400.00 MB transferred (320.32 MB/sec)

Test execution summary:
total time: 320.9155s
total number of events: 104857600
total time taken by event execution: 244.8399
per-request statistics:
min: 0.00ms
avg: 0.00ms
max: 139.41ms
approx. 95 percentile: 0.00ms

Threads fairness:
events (avg/stddev): 104857600.0000/0.00
execution time (avg/stddev): 244.8399/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential write (creation) test
Threads started!
Done.

Operations performed: 0 Read, 131072 Write, 128 Other = 131200 Total
Read 0b Written 2Gb Total transferred 2Gb (320.1Mb/sec)
20251.32 Requests/sec executed

Test execution summary:
total time: 6.9972s
total number of events: 131072
total time taken by event execution: 5.2246
per-request statistics:
min: 0.01ms
avg: 0.04ms
max: 96.76ms
approx. 95 percentile: 0.03ms

Threads fairness:
events (avg/stddev): 131072.0000/0.00
execution time (avg/stddev): 5.2246/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential read test
Threads started!
Done.

Operations performed: 131072 Read, 0 Write, 0 Other = 131072 Total
Read 2Gb Written 0b Total transferred 2Gb (91.32Mb/sec)
5844.8 Requests/sec executed

Test execution summary:
total time: 23.1054s
total number of events: 131072
total time taken by event execution: 22.9933
per-request statistics:
min: 0.00ms
avg: 0.18ms
max: 295.75ms
approx. 95 percentile: 0.77ms

Threads fairness:
events (avg/stddev): 131072.0000/0.00
execution time (avg/stddev): 22.9933/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Number of random requests for random IO: 10000
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Threads started!
Done.

Operations performed: 6000 Read, 4000 Write, 12800 Other = 22800 Total
Read 93.75Mb Written 62.5Mb Total transferred 156.25Mb (1341.5Kb/sec)
85.61 Requests/sec executed

Test execution summary:
total time: 152.9786s
total number of events: 10000
total time taken by event execution: 14.1879
per-request statistics:
min: 0.01ms
avg: 1.41ms
max: 210.22ms
approx. 95 percentile: 4.95ms

Threads fairness:
events (avg/stddev): 10000.0000/0.00
execution time (avg/stddev): 14.1879/0.00

Nəticələr göstəricidir, lakin yenə də QoS kimi qəbul edilməməlidir. 

Əlavə yük yaradan maşınlar

Proqram təminatı:

  • apt-get yeniləmə
  • apt-get yükseltme
  • apt-get quraşdırma python-pip
  • pip quraşdırın mysql-connector-python-rf

Quraşdırılmış MariaDB, Necə burada:

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

Test bazası götürüldü buradan:

Verilənlər bazası göstərildiyi kimi yerləşdirilir burada:

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

Kiçik test bazası:

Masa 

Satırların sayı 

Data ölçüsü (MB)

İndeks ölçüsü (KB)

şöbələri 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

şöbə müdiri 

24 

0.02

16.00

işçilərin 

299379 

14.52

0.00

əmək haqqı 

2838426 

95.63

0.00 

başlıqları 

442783 

19.56

0.00

Python-da diz üzərində primitiv test xidməti yazılıb, o, dörd əməliyyatı yerinə yetirir:

  1. getState: statusu qaytarır
  2. getEmployee: verilənlər bazasından işçiləri (+maaşlar, +titullar) qaytarır
  3. patchEmployee: işçi sahələrini dəyişir
  4. insertMaaş: əmək haqqı əlavə edir

Xidmət mənbəyi (dbtest.py)

#!/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')

Diqqət! Heç bir halda bu xidmət nümunə və ya bələdçi kimi qəbul edilməməlidir!

Testlər yaxşı köhnə JMeter istifadə edərək həyata keçirilir. 15 dəqiqədən 2 saata qədər davam edən testlər seriyası fasiləsiz olaraq başladıldı, sorğuların faizi müxtəlif idi və ötürmə qabiliyyəti dəqiqədə 300-dən 600 sorğuya qədər dəyişdi. 50-dən 500-ə qədər iplərin sayı.

Verilənlər bazası çox kiçik olduğuna görə əmr:

mysql -e "SHOW ENGINE INNODB STATUS"

Bunu göstərir:

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

Aşağıda sorğular üçün orta cavab müddətləri verilmişdir:

etiket

orta

Median

90% Xətt

95% Xətt

99% Xətt

Min

Max

İşçi alın

37.64

12.57

62.28

128.5

497.57

5

4151.78

getState

17

7.57

30.14

58.71

193

3

2814.71

patch İşçi

161.42

83.29

308

492.57

1845.14

5

6639.4

maaş qoymaq

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Bu sintetik nəticələrə əsasən bu VPS-nin sizin konkret tapşırıqlarınız üçün nə dərəcədə uyğun olduğunu mühakimə etmək sizin üçün çətin ola bilər və ümumiyyətlə, sadalanan üsullar bu və ya digər formada həll etməli olduğumuz hallarla məhdudlaşır. açıq-aydın tam deyil. Sizi öz nəticənizi çıxarmağa və real tətbiqlərinizə və tapşırıqlarınıza görə serveri 30 rubla sınamağa dəvət edirik və şərhlərdə bu konfiqurasiya üçün seçimlərinizi təklif edirik.

Mənbə: www.habr.com

Добавить комментарий