Moħħ + VPS għal 30 rublu =?

Huwa daqshekk sabiħ meta l-affarijiet żgħar kollha meħtieġa huma fil-idejn: pinna tajba u notepad, lapes sharpened, ġurdien komdu, ftit wajers żejda, eċċ. Dawn l-affarijiet li ma jidhrux ma jiġbdux l-attenzjoni, iżda jżidu l-kumdità għall-ħajja. L-istess storja hija ma 'diversi applikazzjonijiet mobbli u desktop: għal screenshots twal, għat-tnaqqis tad-daqs ta' stampa, għall-kalkolu tal-finanzi personali, dizzjunarji, tradutturi, konvertituri, eċċ. Għandek waħda? VPS - li huwa rħas, dejjem fil-idejn u jġib ħafna benefiċċji? Le, mhux dik li għandek fil-kumpanija tiegħek, imma waħda tiegħek, "but". Ħsibna li mingħajr VPS żgħir fl-2019 kien b'xi mod imdejjaq, bħal mingħajr il-pinna funtana tas-soltu waqt lecture. Għaliex tkun imdejjaq? Huwa sajf. Kif inhu s-sajf? Sajf għal speċjalista tal-IT: bilqiegħda d-dar, taħdem fuq il-proġetti favoriti tiegħek mingħajr ebda dispjaċir. B'mod ġenerali, ħsibna u għamilna.

Moħħ + VPS għal 30 rublu =?
Il-komuniżmu wasal, sħabi.

Huwa hekk - VPS tagħna għal tletin

Qrajna ħafna artikli minn kompetituri u utenti li kitbu 3-4 snin ilu dwar għaliex mhux meħtieġ VPS rħas. Ukoll, hekk hu, allura VPS "għal Penny" kien marketing pur u ma setax joffri opportunitajiet ta 'xogħol normali. Iżda ż-żminijiet qed jinbidlu, l-ispiża tar-riżorsi virtwali qed issir dejjem aktar baxxa, u għal 30 rublu fix-xahar aħna lesti li noffru dan:

  • Proċessur: Intel Xeon 2 GHz (qalba waħda)
  • Sistema Linux (Debian, Ubuntu, CentOS minn fejn tagħżel)
  • 1 indirizz IPv4 iddedikat
  • 10 GB ta 'ħażna ta' dejta fuq drives SSD veloċi ta 'klassi intrapriża
  • RAM: 512 MB
  • Billing kull sekonda
  • Traffiku bla limitu

It-tariffa hija soġġetta għal restrizzjonijiet tekniċi addizzjonali, dettalji dwar paġna l-offerta friska tagħna - VPS għal 30 rublu. 

Għal min hu adattat dan is-server virtwali? Iva għal kważi kulħadd: jibdew, dilettanti, żviluppaturi b'esperjenza, fannijiet DIY u anke xi kumpaniji.

Għal xiex huwa adattat dan il-VPS?

Aħna naħsbu li l-qarrejja ta 'Habr definittivament se jsibu l-mod tagħhom kif jużaw din il-konfigurazzjoni, iżda ddeċidejna li niġbru l-għażla tagħna stess ta' ideat - x'jiġri jekk xi ħadd ikollu bżonnha, iżda l-irġiel ma jafux?

  • Poġġi l-websajt sempliċi tiegħek, il-portafoll, ibda bil-kodiċi, eċċ. Naturalment, il-websajt iddisinjata tiegħek stess tagħmel impressjoni pożittiva fuq min iħaddem. Poġġiha fuq il-VPS tiegħek u kun responsabbli għas-sigurtà u l-istabbiltà tas-sit lilek innifsek, u mhux mill-istaff ta 'fornituri regolari ta' hosting.
  • Uża VPS għal skopijiet edukattivi: ospita l-proġett tiegħek, studja l-karatteristiċi tas-sistema operattiva tas-server u tas-server, esperimenta bid-DNS, tgħaqqad ma 'sit edukattiv żgħir.
  • Għat-telefonija. Xi drabi intraprenditur individwali, freelancer jew kumpanija żgħira ħafna għandhom bżonn id-disprat tat-telefonija IP, u l-operaturi ta 'din it-telefonija stess huma greedy ħafna. Huwa sempliċi: nieħdu s-server tagħna, nixtru numru mingħand operatur tat-telefonija IP, inwaqqfu PBX virtwali u noħolqu numri interni (jekk meħtieġ). L-iffrankar huwa enormi.
  • Uża s-server biex tittestja l-applikazzjonijiet tiegħek.
  • Uża s-server għal esperimenti DIY, inkluż il-kontroll u l-ġbir tad-dejta minn sensuri tas-sistema tad-dar intelliġenti.
  • Mod mhux tas-soltu biex tużah huwa li tpoġġi assistent tal-kummerċ tal-iskambju virtwali, robot tal-kummerċ, fuq is-server. Int tkun kompletament responsabbli għall-istabbiltà u s-sigurtà tas-server, li jfisser li tirċievi strument ikkontrollat ​​għall-kummerċ fis-swieq tal-ishma. Ukoll, f'każ li xi ħadd ikun interessat jew jippjana :)

Hemm applikazzjonijiet għal tali VPS fl-isfera korporattiva. Minbarra s-servizz tat-telefon diġà msemmi, tista 'timplimenta diversi affarijiet interessanti. Pereżempju:

  • Poġġi databases żgħar u informazzjoni li tkun aċċessibbli għall-impjegati li jivvjaġġaw mill-bogħod, pereżempju, bl-użu tal-ftp. Dan jippermettilek tiskambja malajr ħafna analitiċi ġodda, konfigurazzjonijiet aġġornati għal nies tal-bejgħ, preżentazzjonijiet, eċċ.
  • Agħti aċċess temporanju lill-utenti jew lill-klijenti biex juru softwer jew midja.

VPS test drive għal 30 rublu - magħmul għalik

30 rublu hija tant żgħira li lanqas trid tieħu karta biex tħallas u tittestja. Aħna kultant daqshekk għażżien ukoll, imma din id-darba għamilna kollox għalik. Qabel tniedi s-servers fil-battalja, għamilna test biex niċċekkjaw id-dettalji kollha u nuru x'inhuma s-servers kapaċi b'din it-tariffa. Biex tagħmilha aktar interessanti, żidna estremi u vverifikajna kif din il-konfigurazzjoni kienet se taġixxi jekk id-densità u t-tagħbija jaqbżu l-valuri li ssettjaw. 

L-ospitant kien taħt it-tagħbija ta 'numru ta' magni virtwali li wettqu diversi kompiti fuq il-proċessur u użaw b'mod attiv is-subsistema tad-disk. L-għan huwa li tissimula densità għolja ta 'tqegħid u tagħbija komparabbli ma' jew akbar minn waħda ta 'ġlieda.

Minbarra t-tagħbija kostanti, installajna 3 magni virtwali li ġabru metriċi sintetiċi bl-użu ta 'sysbench, li r-riżultati medji tagħhom ingħataw hawn taħt, u 50 magni virtwali li ħolqu tagħbija addizzjonali. Il-magni virtwali tat-test kollha kellhom l-istess konfigurazzjoni (qalba 1, RAM 512 GB, SSD 10 GB), l-immaġni standard debian 9.6 intgħażlet bħala s-sistema operattiva, li hija offruta lill-utenti fuq RUVDS.

It-tagħbija kienet simulata fin-natura u l-kobor komparabbli mal-ġlieda kontra:

  • Xi magni virtwali ġew imnedija b'tagħbija baxxa
  • Xi magni mexxew skript tat-test li jissimula t-tagħbija fuq il-proċessur (bl-użu tal-utilità istress)
  • Fuq il-bqija tal-magni virtwali, għamilna script li uża dd biex tikkopja dejta minn dejta ppreparata minn qabel għal disk b'sett ta' limitu bl-użu ta' pv (eżempji jistgħu jidhru hawn и hawn).

Ukoll, kif tiftakar, kellna tliet magni li ġabru metriċi sintetiċi.

Fuq kull magna, skript kien eżegwit ċiklikament kull 15-il minuta, li jmexxi testijiet standard sysbench għall-proċessur, memorja u disk.

Script 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

Ir-riżultati huma ppreżentati għall-konvenjenza f'format sysbench, iżda l-valuri medji għall-perjodu kollu tal-ittestjar ittieħdu mill-magni kollha, ir-riżultat jista 'jara hawn:

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

Ir-riżultati huma indikattivi, iżda xorta m'għandhomx jittieħdu bħala QoS. 

Magni li joħolqu tagħbija addizzjonali

Softwer:

  • apt-nikseb aġġornament
  • apt-get upgrade
  • apt-get tinstalla python-pip
  • pip install mysql-connector-python-rf

Installat MariaDB, Kif hawn:

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

Bażi tat-test meħuda għalhekk:

Id-database hija skjerata kif speċifikat hawn:

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

Bażi żgħira tat-test:

Tabella 

RowsCount 

Daqs tad-dejta (MB)

Daqs tal-indiċi (KB)

dipartimenti 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

dept_manager 

24 

0.02

16.00

impjegati 

299379 

14.52

0.00

salarji 

2838426 

95.63

0.00 

titoli 

442783 

19.56

0.00

Servizz ta 'test primittiv huwa miktub fuq l-irkoppa f'Python; iwettaq erba' operazzjonijiet:

  1. getState: jirritorna l-istatus
  2. getEmployee: jirritorna impjegati (+salarji, +titli) mid-database
  3. patchEmployee: jibdel l-oqsma tal-impjegati
  4. daħħalSalarju: daħħal salarju

Sors tas-servizz (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')

Attenzjoni! Taħt l-ebda ċirkostanza dan is-servizz m’għandu jittieħed bħala eżempju jew gwida!

It-testijiet isiru bl-użu ta 'JMeter antik tajjeb. Ġew imnedija serje ta 'testijiet li jdumu minn 15-il minuta sa sagħtejn, mingħajr interruzzjonijiet, il-perċentwal ta' talbiet varja, u t-trażmissjoni varja minn 2 sa 300 talba kull minuta. Numru ta 'ħjut minn 600 sa 50.

Minħabba l-fatt li d-database hija żgħira ħafna, il-kmand:

mysql -e "SHOW ENGINE INNODB STATUS"

Juri li:

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

Hawn taħt huma l-ħinijiet medji ta' rispons għat-talbiet:

tikketta

medja

Medjan

90% Linja

95% Linja

99% Linja

Min

Max

getEmployee

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

garżaEmployee

161.42

83.29

308

492.57

1845.14

5

6639.4

putSalarju

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Jista' jkun diffiċli għalik li tiġġudika minn dawn ir-riżultati sintetiċi kemm dan il-VPS huwa adattat għall-kompiti speċifiċi tiegħek u, b'mod ġenerali, il-metodi elenkati huma limitati għal dawk il-każijiet li kellna nittrattaw magħhom f'xi forma jew oħra. Allura l-lista tagħna hija jidher ċar li mhux eżawrjenti. Nistednuk biex tiġbed il-konklużjonijiet tiegħek stess u tittestja s-server għal 30 rublu fuq l-applikazzjonijiet u l-kompiti reali tiegħek u tissuġġerixxi l-għażliet tiegħek għal din il-konfigurazzjoni fil-kummenti.

Sors: www.habr.com

Żid kumment