Hersenen + VPS voor 30 roebel =?

Het is zo fijn als alle noodzakelijke kleine dingen bij de hand zijn: een goede pen en notitieblok, een geslepen potlood, een comfortabele muis, een paar extra draden, enz. Deze onopvallende dingen trekken geen aandacht, maar voegen comfort toe aan het leven. Hetzelfde verhaal geldt voor verschillende mobiele en desktopapplicaties: voor lange screenshots, voor het verkleinen van een afbeelding, voor het berekenen van persoonlijke financiën, woordenboeken, vertalers, converters, enz. Heb je er een? VPS - wat goedkoop is, altijd bij de hand en veel voordelen met zich meebrengt? Nee, niet degene die u in uw bedrijf heeft, maar uw eigen ‘pocket’-exemplaar. Wij vonden dat het zonder kleine VPS anno 2019 op de een of andere manier triest was, net als zonder de gebruikelijke vulpen bij een lezing. Waarom verdrietig zijn? Het is zomer. Hoe is de zomer? Zomer voor een IT-specialist: thuis zitten en zonder spijt aan je favoriete projecten werken. Over het algemeen dachten en deden we het.

Hersenen + VPS voor 30 roebel =?
Het communisme is gearriveerd, kameraden.

Zo is hij: onze VPS voor dertig

We hebben veel artikelen gelezen van concurrenten en gebruikers die 3-4 jaar geleden schreven over waarom een ​​goedkope VPS niet nodig is. Nou, dat klopt, dan was VPS “voor een cent” pure marketing en kon het geen normale werkmogelijkheden bieden. Maar de tijden veranderen, de kosten van virtuele bronnen worden steeds lager, en voor 30 roebel per maand zijn we klaar om dit aan te bieden:

  • Processor: Intel Xeon 2 GHz (1 kern)
  • Linux-systeem (Debian, Ubuntu, CentOS om uit te kiezen)
  • 1 speciaal IPv4-adres
  • 10 GB gegevensopslag op snelle SSD-schijven van ondernemingsklasse
  • RAM-geheugen: 512MB
  • Facturering per seconde
  • Onbeperkt verkeer

Het tarief is onderworpen aan aanvullende technische beperkingen, details op pagina ons coole aanbod - VPS voor 30 roebel. 

Voor wie is deze virtuele server geschikt? Ja tegen bijna iedereen: beginners, liefhebbers, ervaren ontwikkelaars, doe-het-zelf-fans en zelfs sommige bedrijven.

Waar is deze VPS geschikt voor?

We denken dat de lezers van Habr zeker hun eigen manier zullen vinden om deze configuratie te gebruiken, maar we hebben besloten onze eigen selectie van ideeën te verzamelen - wat als iemand het nodig heeft, maar de mannen weten het niet?

  • Plaats uw eenvoudige website, portfolio, CV met code, etc. Uiteraard maakt uw eigen ontworpen website een positieve indruk bij de werkgever. Plaats hem op je VPS en draag zelf de verantwoordelijkheid voor de veiligheid en stabiliteit van de site, en niet door het personeel van reguliere hostingproviders.
  • Gebruik VPS voor educatieve doeleinden: host uw project, bestudeer de functies van de server en het serverbesturingssysteem, experimenteer met DNS, sleutelen aan een kleine educatieve site.
  • Voor telefonie. Soms heeft een individuele ondernemer, freelancer of een heel klein bedrijf dringend behoefte aan IP-telefonie, en de exploitanten van deze telefonie zijn erg hebzuchtig. Het is eenvoudig: we nemen onze server, kopen een nummer bij een IP-telefonieoperator, zetten een virtuele PBX op en creëren interne nummers (indien nodig). De besparingen zijn enorm.
  • Gebruik de server om uw applicaties te testen.
  • Gebruik de server voor doe-het-zelf-experimenten, waaronder het besturen en verzamelen van gegevens van smart home-systeemsensoren.
  • Een ongebruikelijke manier om het te gebruiken is door een virtuele handelsassistent, een handelsrobot, op de server te plaatsen. U bent volledig verantwoordelijk voor de stabiliteit en veiligheid van de server, wat betekent dat u een gecontroleerd instrument ontvangt voor het handelen op de aandelenmarkten. Nou ja, voor het geval iemand geïnteresseerd is of van plan is :)

Er zijn toepassingen voor dergelijke VPS in de zakelijke sfeer. Naast de reeds genoemde telefoondienst kunt u een aantal interessante zaken implementeren. Bijvoorbeeld:

  • Plaats kleine databases en informatie die op afstand toegankelijk zijn voor reizende medewerkers, bijvoorbeeld via ftp. Hierdoor kunt u zeer snel nieuwe analyses, bijgewerkte configuraties voor verkopers, presentaties, enz. uitwisselen.
  • Geef tijdelijke toegang aan gebruikers of klanten om software of media te demonstreren.

VPS-proefrit voor 30 roebel - voor u gedaan

30 roebel is zo weinig dat je niet eens een kaart wilt pakken om te betalen en te testen. Wij zijn soms ook zo lui, maar deze keer hebben we alles voor je gedaan. Voordat we de servers in de strijd lanceerden, hebben we een test uitgevoerd om alle details te controleren en te laten zien waartoe de servers in staat zijn tegen dit tarief. Om het interessanter te maken, hebben we extreem toegevoegd en gecontroleerd hoe deze configuratie zich zou gedragen als de dichtheid en belasting de door ons ingestelde waarden zouden overschrijden. 

De host stond onder de belasting van een aantal virtuele machines die verschillende taken op de processor uitvoerden en actief gebruik maakten van het schijfsubsysteem. Het doel is om een ​​hoge plaatsingsdichtheid en een belasting te simuleren die vergelijkbaar is met of groter is dan die van een gevecht.

Naast de constante belasting hebben we drie virtuele machines geïnstalleerd die synthetische statistieken verzamelden met behulp van sysbench, waarvan de gemiddelde resultaten hieronder worden weergegeven, en vijftig virtuele machines die voor extra belasting zorgden. Alle virtuele testmachines hadden dezelfde configuratie (3 core, RAM 50 GB, SSD 1 GB), als besturingssysteem werd de standaard debian 512-image geselecteerd, die aan gebruikers op RUVDS wordt aangeboden.

De belasting werd qua aard en omvang vergelijkbaar met gevechten gesimuleerd:

  • Sommige virtuele machines zijn gelanceerd met een lage belasting
  • Sommige machines voerden een testscript uit dat de belasting van de processor simuleerde (met behulp van het hulpprogramma spanning)
  • Op het resterende deel van de virtuele machines hebben we een script uitgevoerd dat dd gebruikte om gegevens van vooraf voorbereide gegevens naar schijf te kopiëren met een limiet ingesteld met behulp van pv (voorbeelden zijn te zien hier и hier).

Zoals u zich herinnert, hadden we ook drie machines die synthetische statistieken verzamelden.

Op elke machine werd cyclisch elke 15 minuten een script uitgevoerd, dat standaard sysbench-tests uitvoert voor de processor, het geheugen en de schijf.

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

De resultaten worden voor het gemak gepresenteerd in sysbench-formaat, maar de gemiddelde waarden voor de gehele testperiode zijn van alle machines overgenomen, het resultaat is hier te zien:

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

De resultaten zijn indicatief, maar mogen nog steeds niet als QoS worden beschouwd. 

Machines die extra belasting creëren

Software:

  • apt-get update
  • apt-get-upgrade
  • apt-get installeer python-pip
  • pip installeer mysql-connector-python-rf

MariaDB geïnstalleerd, hoe hier:

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

Testbasis genomen vandaar:

De database wordt geïmplementeerd zoals opgegeven hier:

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

Kleine testbasis:

tafel 

Rijentelling 

Gegevensgrootte (MB)

Indexgrootte (KB)

afdelingen 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

afdeling_manager 

24 

0.02

16.00

medewerkers 

299379 

14.52

0.00

salarissen 

2838426 

95.63

0.00 

titels 

442783 

19.56

0.00

Een primitieve testservice wordt in Python op de knie geschreven en voert vier bewerkingen uit:

  1. getStat: retourneert de status
  2. getEmployee: retourneert werknemers (+salarissen, +titels) uit de database
  3. patchEmployee: wijzigt medewerkervelden
  4. insertSalary: voegt een salaris in

Servicebron (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')

Waarschuwing! Deze service mag in geen geval als voorbeeld of leidraad worden beschouwd!

Tests worden uitgevoerd met behulp van de goede oude JMeter. Er werd een reeks tests gelanceerd van 15 minuten tot 2 uur, zonder onderbrekingen, het percentage verzoeken varieerde en de doorvoer varieerde van 300 tot 600 verzoeken per minuut. Aantal draden van 50 tot 500.

Vanwege het feit dat de database erg klein is, is het commando:

mysql -e "SHOW ENGINE INNODB STATUS"

Laat zien dat:

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

Hieronder vindt u de gemiddelde responstijden voor verzoeken:

label

Gemiddelde

Mediaan

90%Lijn

95%Lijn

99%Lijn

min

Max

krijgenWerknemer

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

patchWerknemer

161.42

83.29

308

492.57

1845.14

5

6639.4

zetSalaris

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Het kan voor u moeilijk zijn om op basis van deze synthetische resultaten te beoordelen hoe geschikt deze VPS is voor uw specifieke taken en over het algemeen zijn de genoemde methoden beperkt tot die gevallen waarmee we op de een of andere manier te maken hebben gehad. duidelijk niet uitputtend. We nodigen u uit om uw eigen conclusies te trekken en de server voor 30 roebel te testen op uw echte applicaties en taken en uw opties voor deze configuratie in de opmerkingen voor te stellen.

Bron: www.habr.com

Voeg een reactie