Smadzenes + VPS par 30 rubļiem =?

Ir tik jauki, kad pa rokai ir visi nepiecieÅ”amie sÄ«kumi: laba pildspalva un piezÄ«mju blociņŔ, uzasināts zÄ«mulis, ērta pele, pāris lieki vadi utt. Å Ä«s neuzkrÄ«toŔās lietas nepiesaista uzmanÄ«bu, bet pieŔķir dzÄ«vei komfortu. Tas pats stāsts ir ar dažādām mobilajām un darbvirsmas aplikācijām: gariem ekrānuzņēmumiem, attēla izmēra samazināŔanai, personÄ«go finanÅ”u aprēķināŔanai, vārdnÄ«cām, tulkotājiem, konvertētājiem utt. Vai tev ir viens? VPS - kas ir lēts, vienmēr pa rokai un sniedz daudz priekÅ”rocÄ«bu? Nē, nevis tas, kas jums ir jÅ«su uzņēmumā, bet jÅ«su, ā€œkabatasā€. Domājām, ka bez mazā VPS 2019. gadā bija kaut kā skumji, gluži kā bez parastās tintes pildspalvas lekcijā. Kāpēc skumt? Ir vasara. kā vasara? Vasara IT speciālistam: sēdēt mājās, bez nožēlas strādāt pie iecienÄ«tākajiem projektiem. Kopumā domājām un izdarÄ«jām.

Smadzenes + VPS par 30 rubļiem =?
Komunisms ir klāt, biedri.

ViņŔ ir tāds - mÅ«su VPS par trÄ«sdesmit

Mēs esam lasÄ«juÅ”i daudz rakstu no konkurentiem un lietotājiem, kuri rakstÄ«ja pirms 3-4 gadiem par to, kāpēc nav nepiecieÅ”ams lēts VPS. Nu, tieÅ”i tā, tad VPS ā€œpar santÄ«muā€ bija tÄ«rais mārketings un nevarēja piedāvāt normālas darba iespējas. Bet laiki mainās, virtuālo resursu izmaksas kļūst arvien zemākas, un par 30 rubļiem mēnesÄ« mēs esam gatavi piedāvāt Å”o:

  • Procesors: Intel Xeon 2 GHz (1 kodols)
  • Linux sistēma (no kuriem izvēlēties Debian, Ubuntu, CentOS)
  • 1 Ä«paÅ”a IPv4 adrese
  • 10 GB datu krātuve ātros uzņēmuma klases SSD diskos
  • RAM: 512 MB
  • Norēķini par sekundi
  • Neierobežota satiksme

Uz tarifu attiecas papildu tehniskie ierobežojumi, sÄ«kāk par lappuse mÅ«su forÅ”ais piedāvājums - VPS par 30 rubļiem. 

Kam Å”is virtuālais serveris ir piemērots? Jā gandrÄ«z visiem: iesācējiem, entuziastiem, pieredzējuÅ”iem izstrādātājiem, DIY faniem un pat dažiem uzņēmumiem.

Kam Å”is VPS ir piemērots?

Mēs domājam, ka Habr lasÄ«tāji noteikti atradÄ«s savu veidu, kā izmantot Å”o konfigurāciju, taču mēs nolēmām apkopot savu ideju izlasi - ja nu kādam tas ir vajadzÄ«gs, bet vÄ«rieÅ”i nezina?

  • Ievietojiet savu vienkārÅ”o vietni, portfolio, CV ar kodu utt. Protams, jÅ«su izveidotā vietne atstāj pozitÄ«vu iespaidu uz darba devēju. Ievietojiet to savā VPS un esiet atbildÄ«gs par vietnes droŔību un stabilitāti pats, nevis parasto mitināŔanas pakalpojumu sniedzēju darbinieki.
  • Izmantojiet VPS izglÄ«tojoÅ”iem nolÅ«kiem: mitiniet savu projektu, izpētiet servera un servera operētājsistēmas iespējas, eksperimentējiet ar DNS, izdomājiet nelielu izglÄ«tojoÅ”u vietni.
  • Telefonijai. Dažreiz individuālam uzņēmējam, ārÅ”tata darbiniekam vai ļoti mazam uzņēmumam ļoti nepiecieÅ”ama IP telefonija, un tieÅ”i Ŕīs telefonijas operatori ir ļoti mantkārÄ«gi. Tas ir vienkārÅ”i: mēs paņemam savu serveri, nopērkam numuru no IP telefonijas operatora, izveidojam virtuālo PBX un izveidojam iekŔējos numurus (ja nepiecieÅ”ams). IetaupÄ«jumi ir milzÄ«gi.
  • Izmantojiet serveri, lai pārbaudÄ«tu savas lietojumprogrammas.
  • Izmantojiet serveri DIY eksperimentiem, tostarp datu kontrolei un datu apkopoÅ”anai no viedās mājas sistēmas sensoriem.
  • Neparasts veids, kā to izmantot, ir novietot uz servera virtuālo biržas tirdzniecÄ«bas palÄ«gu, tirdzniecÄ«bas robotu. JÅ«s bÅ«siet pilnÄ«bā atbildÄ«gs par servera stabilitāti un droŔību, kas nozÄ«mē, ka saņemsiet kontrolētu instrumentu tirdzniecÄ«bai akciju tirgos. Nu ja kādam interesē vai plāno :)

KorporatÄ«vajā sfērā ir Ŕādas VPS lietojumprogrammas. Papildus jau pieminētajam telefonpakalpojumam var Ä«stenot vairākas interesantas lietas. Piemēram:

  • Ievietojiet nelielas datu bāzes un informāciju, kas bÅ«s pieejama ceļojoÅ”ajiem darbiniekiem no attāluma, piemēram, izmantojot ftp. Tas ļaus jums ļoti ātri apmainÄ«ties ar svaigu analÄ«zi, atjauninātām konfigurācijām pārdevējiem, prezentācijām utt.
  • PieŔķiriet lietotājiem vai klientiem pagaidu piekļuvi, lai demonstrētu programmatÅ«ru vai multividi.

VPS testa brauciens par 30 rubļiem - darīts jūsu vietā

30 rubļi ir tik maz, ka pat negribas izņemt karti, lai samaksātu un pārbaudÄ«tu. ArÄ« mēs reizēm esam tik slinki, bet Å”oreiz visu izdarÄ«jām jÅ«su vietā. Pirms serveru palaiÅ”anas kaujā mēs veicām testu, lai pārbaudÄ«tu visas detaļas un parādÄ«tu, uz ko serveri ir spējÄ«gi ar Å”o tarifu. Lai padarÄ«tu to interesantāku, mēs pievienojām ekstrēmu un pārbaudÄ«jām, kā Ŕī konfigurācija darbotos, ja blÄ«vums un slodze pārsniegtu mÅ«su iestatÄ«tās vērtÄ«bas. 

Uzņēmējs bija zem vairāku virtuālo maŔīnu slodzes, kas veica dažādus procesora uzdevumus un aktÄ«vi izmantoja diska apakÅ”sistēmu. MērÄ·is ir simulēt augstu izvietojuma blÄ«vumu un slodzi, kas ir salÄ«dzināma ar kaujas slodzi vai lielāka par to.

Papildus pastāvÄ«gajai slodzei mēs uzstādÄ«jām 3 virtuālās maŔīnas, kas apkopoja sintētiskos rādÄ«tājus, izmantojot sysbench, kuru vidējie rezultāti tika norādÄ«ti zemāk, un 50 virtuālās maŔīnas, kas radÄ«ja papildu slodzi. Visām testa virtuālajām maŔīnām bija vienāda konfigurācija (1 kodols, RAM 512 GB, SSD 10 GB), kā operētājsistēma tika izvēlēts standarta debian 9.6 attēls, kas tiek piedāvāts lietotājiem RUVDS.

Slodze tika simulēta pēc būtības un lieluma, kas ir salīdzināma ar cīņu:

  • Dažas virtuālās maŔīnas tika palaistas ar zemu slodzi
  • Dažas maŔīnas palaida testa skriptu, kas simulē procesora slodzi (izmantojot utilÄ«tu uzsvars)
  • AtlikuÅ”ajā virtuālo maŔīnu daļā mēs palaidām skriptu, kas izmantoja dd, lai kopētu datus no iepriekÅ” sagatavotiem datiem uz disku ar ierobežojumu, kas iestatÄ«ts, izmantojot pv (var redzēt piemērus Å”eit Šø Å”eit).

Turklāt, kā jÅ«s atceraties, mums bija trÄ«s maŔīnas, kas apkopoja sintētiskos rādÄ«tājus.

Katrā maŔīnā ik pēc 15 minÅ«tēm cikliski tika izpildÄ«ts skripts, kas palaiž standarta procesora, atmiņas un diska sysbench testus.

Skripts 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

ĒrtÄ«bas labad rezultāti ir parādÄ«ti sysbench formātā, bet vidējās vērtÄ«bas visam testÄ“Å”anas periodam tika ņemtas no visām maŔīnām, rezultātu var redzēt Å”eit:

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

Rezultāti ir orientējoÅ”i, taču tos nevajadzētu uzskatÄ«t par QoS. 

MaŔīnas, kas rada papildu slodzi

Programmatūra:

  • apt-get update
  • apt-get jauninājums
  • apt-get instalēt python-pip
  • pip instalēt mysql-connector-python-rf

Instalēta MariaDB, kā Å”eit:

apt-get install libmariadbclient-dev
mysql -e "INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so';" -- Š½ŃƒŠ¶Š½Š¾ Š“Š»Ń test_employees_sha

Pārbaudes bāze ņemta tātad:

Datubāze tiek izvietota, kā norādīts Ŕeit:

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

Maza testa bāze:

Tabula 

Rindu skaits 

Datu lielums (MB)

Indeksa lielums (KB)

departamenti 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

nodaļas vadÄ«tājs 

24 

0.02

16.00

darbinieki 

299379 

14.52

0.00

algas 

2838426 

95.63

0.00 

virsraksti 

442783 

19.56

0.00

Uz ceļa Python ir uzrakstīts primitīvs testa pakalpojums; tas veic četras darbības:

  1. getState: atgriež statusu
  2. getEmployee: atgriež darbiniekus (+algas, +titulus) no datu bāzes
  3. patchEmployee: maina darbinieku laukus
  4. insertSalary: ievieto algu

Pakalpojuma avots (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')

Uzmanību! Šo pakalpojumu nekādā gadījumā nedrīkst uzskatīt par piemēru vai ceļvedi!

Pārbaudes tiek veiktas, izmantojot veco labo JMeter. Tika uzsākta virkne testu, kas ilga no 15 minÅ«tēm lÄ«dz 2 stundām, bez pārtraukumiem, pieprasÄ«jumu procentuālais daudzums mainÄ«jās, un caurlaidspēja svārstÄ«jās no 300 lÄ«dz 600 pieprasÄ«jumiem minÅ«tē. VÄ«tņu skaits no 50 lÄ«dz 500.

Sakarā ar to, ka datu bāze ir ļoti maza, komanda:

mysql -e "SHOW ENGINE INNODB STATUS"

Parāda, ka:

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

Tālāk ir norādīts vidējais pieprasījumu atbildes laiks.

etiÄ·ete

vidējais

Median

90% līnija

95% līnija

99% līnija

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

patchEmployee

161.42

83.29

308

492.57

1845.14

5

6639.4

liktAlga

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Jums var bÅ«t grÅ«ti no Å”iem sintētiskajiem rezultātiem spriest, cik Ŕī VPS ir piemērota jÅ«su konkrētajiem uzdevumiem, un kopumā uzskaitÄ«tās metodes attiecas tikai uz tiem gadÄ«jumiem, kas mums bija jārisina vienā vai otrā veidā. Tātad mÅ«su saraksts ir Ŕāds. nepārprotami nav izsmeļoÅ”s. Aicinām izdarÄ«t savus secinājumus un pārbaudÄ«t serveri par 30 rubļiem uz savām reālajām lietojumprogrammām un uzdevumiem un komentāros ieteikt savas iespējas Å”ai konfigurācijai.

Avots: www.habr.com

Pievieno komentāru