Brain + VPS rau 30 rubles =?

Nws yog qhov zoo heev thaum txhua yam me me uas tsim nyog nyob ntawm tes: tus cwj mem zoo thiab phau ntawv sau, tus cwj mem ntse, tus nas xis nyob, ob peb txuas ntxiv, thiab lwm yam. Tej yam tsis meej pem no tsis nyiam mloog, tab sis ntxiv kev nplij siab rau lub neej. Tib zaj dab neeg yog nrog ntau yam mobile thiab desktop daim ntawv thov: rau ntev screenshots, txo qhov luaj li cas ntawm daim duab, rau xam tus kheej nyiaj txiag, dictionaries, neeg txhais lus, converters, thiab lwm yam. Koj puas muaj ib? VPS - uas yog pheej yig, ib txwm nyob ntawm tes thiab nqa ntau cov txiaj ntsig? Tsis yog, tsis yog ib qho uas koj muaj hauv koj lub tuam txhab, tab sis koj tus kheej, "pocket" ib qho. Peb xav tias tsis muaj VPS me me hauv 2019 nws yog qee qhov kev tu siab, ib yam li tsis muaj tus cwj mem ib txwm nyob ntawm kev qhuab qhia. Ua cas yuav tu siab? Nws yog lub caij ntuj sov. Lub caij ntuj sov zoo li cas? Lub caij ntuj sov rau tus kws tshaj lij IT: zaum hauv tsev, ua haujlwm ntawm koj cov haujlwm nyiam yam tsis muaj kev khuv xim. Feem ntau, peb xav thiab ua nws.

Brain + VPS rau 30 rubles =?
Communism los txog, cov phooj ywg.

Nws zoo li ntawd - peb VPS rau peb caug

Peb tau nyeem ntau cov ntawv los ntawm cov neeg sib tw thiab cov neeg siv uas tau sau 3-4 xyoo dhau los txog vim li cas tus nqi pheej yig VPS tsis xav tau. Zoo, yog lawm, ces VPS "rau ib lub nyiaj" yog kev lag luam dawb huv thiab tsis tuaj yeem muab txoj hauv kev ua haujlwm ib txwm muaj. Tab sis lub sijhawm hloov pauv, tus nqi ntawm cov peev txheej virtual tau qis dua thiab qis dua, thiab rau 30 rubles ib hlis peb npaj siab muab qhov no:

  • Processor: Intel Xeon 2 GHz (1 core)
  • Linux system (Debian, Ubuntu, CentOS xaiv los ntawm)
  • 1 qhov chaw nyob IPv4 tshwj xeeb
  • 10 GB ntawm cov ntaub ntawv khaws cia ntawm cov lag luam ceev ceev SSD drives
  • RAM: 512 MB
  • Ib daim nqi thib ob
  • Unlimited tsheb

Tus nqi tariff yuav raug ntxiv kev txwv, cov ntsiab lus ntawm nplooj ntawv peb qhov kev thov txias - VPS rau 30 rubles. 

Leej twg yog tus neeg rau zaub mov virtual no haum rau? Yog rau yuav luag txhua tus: cov pib tshiab, cov neeg nyiam, cov neeg tsim khoom paub txog, DIY kiv cua thiab txawm tias qee lub tuam txhab.

Qhov no VPS haum rau dab tsi?

Peb xav tias Habr cov neeg nyeem yuav pom lawv tus kheej txoj hauv kev siv qhov kev teeb tsa no, tab sis peb txiav txim siab los sau peb tus kheej xaiv cov tswv yim - yuav ua li cas yog tias ib tug neeg xav tau, tab sis cov txiv neej tsis paub?

  • Muab koj lub vev xaib yooj yim, portfolio, rov pib dua nrog code, thiab lwm yam. Tau kawg, koj tus kheej lub vev xaib tsim ua rau muaj kev xav zoo rau tus tswv haujlwm. Muab tso rau hauv koj tus VPS thiab ua lub luag haujlwm rau kev ruaj ntseg thiab ruaj ntseg ntawm lub xaib koj tus kheej, thiab tsis yog los ntawm cov neeg ua haujlwm ntawm cov chaw muab kev pabcuam.
  • Siv VPS rau kev kawm: tuav koj qhov project, kawm cov yam ntxwv ntawm lub server thiab server operating system, sim nrog DNS, tinker nrog rau qhov chaw kawm me me.
  • Rau xov tooj. Qee lub sij hawm ib tus neeg ua lag luam, tus neeg ua haujlwm ywj pheej lossis lub tuam txhab me me xav tau kev hu xov tooj IP, thiab cov neeg ua haujlwm ntawm lub xov tooj no yog kev ntshaw heev. Nws yog qhov yooj yim: peb nqa peb cov neeg rau zaub mov, yuav tus lej los ntawm tus neeg siv xov tooj IP, teeb tsa lub virtual PBX thiab tsim cov lej sab hauv (yog tias tsim nyog). Cov nyiaj khaws cia yog colossal.
  • Siv lub server los kuaj koj daim ntawv thov.
  • Siv cov neeg rau zaub mov rau DIY thwmsim, nrog rau kev tswj thiab sau cov ntaub ntawv los ntawm lub tsev ntse sensors.
  • Ib txoj hauv kev uas txawv txav los siv nws yog tso tus kws pab cuam pauv pauv pauv virtual, tus neeg hlau ua lag luam, ntawm lub server. Koj yuav muaj lub luag haujlwm tag nrho rau kev ruaj ntseg thiab kev ruaj ntseg ntawm cov neeg rau zaub mov, uas txhais tau tias koj yuav tau txais cov cuab yeej tswj kev lag luam ntawm cov khw muag khoom. Zoo, yog tias leej twg txaus siab los yog npaj :)

Muaj cov ntawv thov rau xws li VPS hauv kev koom tes. Ntxiv nrog rau qhov kev pabcuam xovtooj uas twb tau hais lawm, koj tuaj yeem siv ntau yam nthuav. Piv txwv li:

  • Muab cov ntaub ntawv me me thiab cov ntaub ntawv uas yuav nkag tau rau cov neeg ua haujlwm taug kev ntawm qhov deb, piv txwv li, siv ftp. Qhov no yuav tso cai rau koj los pauv cov kev ntsuas tshiab sai sai, hloov kho cov teeb tsa rau cov neeg muag khoom, kev nthuav qhia, thiab lwm yam.
  • Muab kev nkag mus rau ib ntus rau cov neeg siv lossis cov neeg siv khoom los ua qauv qhia software lossis xov xwm.

VPS xeem tsav rau 30 rubles - ua tiav rau koj

30 rubles tsawg heev uas koj tsis xav rho tawm ib daim npav them thiab kuaj. Peb qee zaum tub nkeeg heev, tab sis lub sijhawm no peb ua txhua yam rau koj. Ua ntej tshaj tawm cov servers rau hauv kev sib ntaus sib tua, peb tau ua qhov kev sim los xyuas tag nrho cov ntsiab lus thiab qhia tias cov servers muaj peev xwm ntawm tus nqi no. Txhawm rau kom nthuav dav ntxiv, peb ntxiv cov huab cua thiab tshuaj xyuas seb qhov kev teeb tsa no yuav coj li cas yog tias qhov ceev thiab thauj khoom dhau ntawm qhov tseem ceeb uas peb tau teeb tsa. 

Tus tswv tsev tau nyob rau hauv lub nra ntawm ntau lub tshuab virtual uas tau ua ntau yam haujlwm ntawm lub processor thiab nquag siv lub disk subsystem. Lub hom phiaj yog simulate qhov siab ceev ntawm kev tso kawm thiab ib qho kev sib piv rau lossis ntau dua ib qho kev sib ntaus sib tua.

Ntxiv rau qhov kev thauj khoom tas mus li, peb tau teeb tsa 3 lub tshuab virtual uas tau sau cov ntsuas hluavtaws siv sysbench, qhov nruab nrab cov txiaj ntsig tau muab rau hauv qab no, thiab 50 lub tshuab virtual uas tsim cov khoom siv ntxiv. Txhua qhov kev sim virtual tshuab muaj tib qhov kev teeb tsa (1 core, RAM 512 GB, SSD 10 GB), tus qauv debian 9.6 duab raug xaiv raws li kev ua haujlwm, uas tau muab rau cov neeg siv ntawm RUVDS.

Lub load tau simulated nyob rau hauv qhov thiab qhov loj me piv rau kev sib ntaus sib tua:

  • Qee lub tshuab virtual tau pib nrog cov khoom qis
  • Qee lub tshuab tau khiav cov ntawv xeem simulating lub nra ntawm lub processor (siv cov nqi hluav taws xob kev nyuaj siab)
  • Ntawm qhov seem ntawm cov tshuab virtual, peb tau khiav ib tsab ntawv uas siv dd los luam cov ntaub ntawv los ntawm cov ntaub ntawv npaj ua ntej rau disk nrog txwv tsis pub siv pv (piv txwv li tuaj yeem pom. no ΠΈ no).

Tsis tas li ntawd, raws li koj nco qab, peb muaj peb lub tshuab uas sau cov khoom siv hluavtaws.

Ntawm txhua lub tshuab, ib tsab ntawv raug tua txhua txhua 15 feeb, uas khiav cov kev xeem sysbench rau lub processor, nco thiab disk.

Tsab ntawv 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

Cov txiaj ntsig tau nthuav tawm kom yooj yim hauv sysbench hom, tab sis qhov nruab nrab qhov tseem ceeb rau tag nrho lub sijhawm xeem tau raug coj los ntawm txhua lub tshuab, cov txiaj ntsig tuaj yeem pom ntawm no:

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

Cov txiaj ntsig tau qhia, tab sis tseem yuav tsum tsis txhob coj ua QoS. 

Cov tshuab uas tsim cov load ntxiv

Software:

  • apt-get update
  • apt-tau txawj tej yam ntxiv
  • apt-mus nruab python-pip
  • pip nruab mysql-connector-python-rf

Nruab MariaDB, Yuav ua li cas S, SΡ“S,:

apt-get install libmariadbclient-dev
mysql -e "INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so';" -- Π½ΡƒΠΆΠ½ΠΎ для test_employees_sha

Test puag coj ntawm no:

Lub database yog deployed raws li tau teev tseg S, SΡ“S,:

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

Me me xeem puag:

rooj 

RowsCount 

Cov ntaub ntawv loj (MB)

Index loj (KB)

saib xyuas 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

dept_manager 

24 

0.02

16.00

neeg ua hauj lwm 

299379 

14.52

0.00

cov nyiaj hli 

2838426 

95.63

0.00 

lub npe 

442783 

19.56

0.00

Ib qho kev sim thawj zaug yog sau rau ntawm lub hauv caug hauv Python; nws ua plaub yam haujlwm:

  1. getState: rov qab cov xwm txheej
  2. getEmployee: xa rov qab cov neeg ua haujlwm (+ nyiaj hli, + npe) los ntawm cov ntaub ntawv
  3. patchEmployee: hloov chaw ua haujlwm
  4. insertSalary: ntxig nyiaj hli

Qhov chaw pabcuam (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')

Ceev faj Tsis muaj qhov xwm txheej yuav tsum tau muab qhov kev pabcuam no ua piv txwv lossis qhia!

Kev ntsuam xyuas tau ua tiav siv JMeter qub. Ib qho kev sim ntsuas ntev li ntawm 15 feeb mus rau 2 teev tau pib, tsis muaj kev cuam tshuam, feem pua ​​​​ntawm kev thov sib txawv, thiab kev sib txawv ntawm 300 txog 600 qhov kev thov ib feeb. Tus naj npawb ntawm threads los ntawm 50 mus rau 500.

Vim lub fact tias cov database me me heev, cov lus txib:

mysql -e "SHOW ENGINE INNODB STATUS"

Qhia tias:

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

Hauv qab no yog lub sijhawm teb nruab nrab rau kev thov:

daim ntawv lo

Nruab nrab

theem nrab

90% Kab

95% Kab

99% Kab

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

patch neeg ua haujlwm

161.42

83.29

308

492.57

1845.14

5

6639.4

putSalary

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Tej zaum nws yuav nyuaj rau koj los txiav txim los ntawm cov txiaj ntsig hluavtaws no tsim nyog li cas VPS no rau koj cov haujlwm tshwj xeeb thiab, feem ntau, cov txheej txheem teev tseg tsuas yog rau cov xwm txheej uas peb yuav tsum tau ua nrog rau hauv ib daim ntawv lossis lwm qhov. kom meej meej tsis tag. Peb caw koj los kos koj tus kheej cov lus xaus thiab sim cov neeg rau zaub mov rau 30 rubles ntawm koj cov ntawv thov tiag tiag thiab cov haujlwm thiab qhia koj cov kev xaiv rau qhov kev teeb tsa no hauv cov lus.

Tau qhov twg los: www.hab.com

Ntxiv ib saib