Otak + VPS pikeun 30 rubles =?

Éta saé pisan nalika sadaya hal-hal anu diperyogikeun aya: pulpén sareng notepad anu saé, pensil anu diasah, beurit anu nyaman, sababaraha kabel tambahan, jsb. Ieu hal inconspicuous teu narik perhatian, tapi nambahan kanyamanan kana kahirupan. Carita anu sami nyaéta kalayan sagala rupa aplikasi mobile sareng desktop: pikeun potret layar panjang, pikeun ngirangan ukuran gambar, pikeun ngitung kauangan pribadi, kamus, penerjemah, konverter, jsb. Dupi anjeun gaduh hiji? VPS - nu murah, salawasna di leungeun jeung mawa loba mangpaat? Henteu, sanés anu anjeun gaduh di perusahaan anjeun, tapi anjeun nyalira, "saku". Kami ngira yén tanpa VPS leutik di 2019 éta kumaha waé hanjelu, sapertos tanpa pulpén cai mancur biasa dina kuliah. Naha sedih? Usum panas. Kumaha usum panas? Usum panas pikeun spesialis IT: linggih di bumi, damel dina proyék karesep anjeun tanpa kuciwa. Sacara umum, urang pikir jeung ngalakukeun eta.

Otak + VPS pikeun 30 rubles =?
Komunisme parantos sumping, sobat.

Anjeunna sapertos kitu - VPS kami tilu puluh

Kami parantos maca seueur tulisan ti pesaing sareng pangguna anu nyerat 3-4 sababaraha taun ka pengker ngeunaan naha VPS murah henteu diperyogikeun. Nya, éta leres, teras VPS "pikeun Penny" mangrupikeun pamasaran murni sareng henteu tiasa nawiskeun kasempetan kerja normal. Tapi waktosna robih, biaya sumber virtual janten langkung handap, sareng 30 rubles sabulan kami siap nawiskeun ieu:

  • Prosesor: Intel Xeon 2 GHz (1 inti)
  • Sistem Linux (Debian, Ubuntu, CentOS pikeun dipilih)
  • 1 alamat IPv4 dedicated
  • 10 GB panyimpen data dina drive SSD kelas perusahaan gancang
  • RAM: 512 MB
  • Tagihan per detik
  • lalulintas Unlimited

tarif nu tunduk kana larangan teknis tambahan, rinci dina kaca tawaran tiis kami - VPS pikeun 30 rubles. 

Saha server virtual ieu cocog pikeun? Sumuhun pikeun ampir sadayana: beginners, peminat, pamekar ngalaman, fans DIY komo sababaraha pausahaan.

Naon VPS ieu cocog?

Kami nyangka yén pamiarsa Habr pasti bakal mendakan cara sorangan pikeun ngagunakeun konfigurasi ieu, tapi kami mutuskeun pikeun ngumpulkeun pilihan ideu sorangan - kumaha upami aya anu peryogina, tapi lalakina henteu terang?

  • Teundeun ramatloka basajan anjeun, portopolio, neruskeun kalawan kode, jsb. Tangtosna, halaman wéb anu dirarancang anjeun nyalira gaduh kesan anu positif pikeun dunungan. Pasang dina VPS anjeun sareng tanggung jawab kana kaamanan sareng stabilitas situs anjeun nyalira, sareng sanés ku staf panyadia hosting biasa.
  • Anggo VPS pikeun tujuan pendidikan: host proyék anjeun, diajar fitur tina server sareng sistem operasi server, ékspérimén sareng DNS, tinker sareng situs atikan leutik.
  • Pikeun telepon. Kadang-kadang pengusaha individu, freelancer atanapi perusahaan alit pisan peryogi telepon IP, sareng operator teleponi ieu pisan rakus. Ieu basajan: urang nyandak server kami, meuli nomer ti operator IP telephony, nyetél PBX maya tur jieun nomer internal (lamun perlu). Tabungan anu kolosal.
  • Anggo server pikeun nguji aplikasi anjeun.
  • Anggo server pikeun percobaan DIY, kalebet ngadalikeun sareng ngumpulkeun data tina sensor sistem bumi pinter.
  • Cara anu teu biasa pikeun dianggo nyaéta nempatkeun asistén dagang bursa virtual, robot dagang, dina server. Anjeun bakal tanggung jawab pinuh pikeun stabilitas sareng kaamanan server, anu hartosna anjeun bakal nampi alat anu dikontrol pikeun dagang di pasar saham. Muhun, upami aya anu minat atanapi ngarencanakeun :)

Aya aplikasi pikeun VPS sapertos dina lingkup perusahaan. Salian jasa telepon anu parantos disebatkeun, anjeun tiasa ngalaksanakeun sababaraha hal anu pikaresepeun. Salaku conto:

  • Teundeun databés leutik sarta informasi anu bakal diasupan ka karyawan iinditan dina kajauhan, contona, ngagunakeun ftp. Ieu bakal ngamungkinkeun anjeun gancang-gancang tukeur analytics seger, konfigurasi anu diropéa pikeun jalma penjualan, presentasi, jsb.
  • Pasihan aksés samentawis ka pangguna atanapi klien pikeun nunjukkeun parangkat lunak atanapi média.

VPS test drive pikeun 30 rubles - dipigawé pikeun anjeun

30 rubles sakedik sahingga anjeun henteu hoyong nyandak kartu pikeun mayar sareng nguji. Kami kadang jadi puguh teuing, tapi waktos ieu kami ngalakukeun sagalana pikeun anjeun. Sateuacan ngaluncurkeun server kana perang, kami ngalaksanakeun tés pikeun mariksa sadaya detil sareng nunjukkeun naon anu sanggup server dina tarif ieu. Pikeun ngajantenkeun langkung narik, kami nambihan ekstrim sareng pariksa kumaha konfigurasi ieu bakal kalakuan upami dénsitas sareng beban ngaleuwihan nilai anu kami setel. 

Host éta dina beban tina sababaraha mesin virtual anu ngalaksanakeun rupa-rupa pancén dina prosésor sareng aktip ngagunakeun subsistem disk. Tujuanana nya éta pikeun simulate kapadetan luhur panempatan sarta beban comparable atawa leuwih gede ti hiji tempur.

Salian beban konstan, kami dipasang 3 mesin virtual anu ngumpulkeun métrik sintétik ngagunakeun sysbench, hasil rata-rata anu dirumuskeun di handap ieu, sareng 50 mesin virtual anu nyiptakeun beban tambahan. Kabéh mesin virtual test miboga konfigurasi sarua (1 inti, RAM 512 GB, SSD 10 GB), standar debian 9.6 gambar ieu dipilih salaku sistem operasi, nu ditawarkeun ka pamaké on RUVDS.

Beban ieu simulated di alam jeung gedena comparable pikeun merangan:

  • Sababaraha mesin virtual diluncurkeun kalayan beban anu rendah
  • Sababaraha mesin ngajalankeun skrip tés simulating beban dina prosésor (ngagunakeun utiliti tekenan)
  • Dina bagian sésana tina mesin virtual, urang ngajalankeun skrip anu ngagunakeun dd pikeun nyalin data tina data anu tos disiapkeun ka disk kalayan set wates nganggo pv (conto tiasa ditingali. di dieu и di dieu).

Ogé, sakumaha anu anjeun émut, kami ngagaduhan tilu mesin anu ngumpulkeun métrik sintétik.

Dina unggal mesin, naskah dieksekusi sacara siklik unggal 15 menit, anu ngajalankeun tés sysbench standar pikeun prosésor, mémori sareng disk.

Skrip 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

Hasilna dipidangkeun pikeun genah dina format sysbench, tapi nilai rata-rata pikeun sakabéh période tés dicandak tina sadaya mesin, hasilna tiasa ditingali di dieu:

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

Hasilna nunjukkeun, tapi tetep henteu kedah dianggap QoS. 

Mesin anu nyiptakeun beban tambahan

Parangkat lunak:

  • update apt-meunang
  • pamutahiran apt-meunang
  • apt-meunang install python-pip
  • pip install mysql-konektor-python-rf

Dipasang MariaDB, Kumaha di dieu:

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

Basis tés dicandak di dieu:

database ieu deployed sakumaha dieusian di dieu:

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

Dasar tés leutik:

meja 

RowsCount 

Ukuran data (MB)

Ukuran indéks (KB)

departemén 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

dept_manager 

24 

0.02

16.00

pagawé 

299379 

14.52

0.00

lacur 

2838426 

95.63

0.00 

judul 

442783 

19.56

0.00

Ladenan uji primitif ditulis dina dengkul dina Python; éta ngalaksanakeun opat operasi:

  1. getState: mulih status
  2. getEmployee: mulih karyawan (+ gaji, + judul) tina database
  3. patchEmployee: robah widang pagawe
  4. insertGaji: ngasupkeun gaji

Sumber jasa (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')

Awas! Dina kaayaan naon waé, jasa ieu kedah dianggap salaku conto atanapi pituduh!

Tés anu dipigawé maké JMeter heubeul alus. Runtuyan tés anu lumangsung ti 15 menit dugi ka 2 jam diluncurkeun, tanpa gangguan, persentase paménta variasina, sareng throughput variasina tina 300 dugi ka 600 pamundut per menit. Jumlah threads ti 50 nepi ka 500.

Kusabab kanyataan yén pangkalan data leutik pisan, paréntahna:

mysql -e "SHOW ENGINE INNODB STATUS"

Némbongkeun yén:

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

Di handap ieu mangrupikeun waktos réspon rata-rata pikeun pamundut:

etiket

rata-rata

median

90% Jalur

95% Jalur

99% Jalur

min

Max

meunangPagawe

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

patchPagawe

161.42

83.29

308

492.57

1845.14

5

6639.4

nempatkeun Gaji

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Panginten sesah pikeun anjeun pikeun nangtoskeun tina hasil sintétis ieu kumaha cocogna VPS ieu pikeun tugas-tugas khusus anjeun sareng, sacara umum, metode anu didaptarkeun dugi ka kasus-kasus anu kedah urang laksanakeun dina hiji bentuk atanapi anu sanés. jelas teu tuntas. Kami ngajak anjeun ngagambar kacindekan sorangan sareng nguji server pikeun 30 rubles dina aplikasi sareng tugas nyata anjeun sareng nyarankeun pilihan anjeun pikeun konfigurasi ieu dina koméntar.

sumber: www.habr.com

Tambahkeun komentar