Тархи + VPS 30 рубль =?

Сайн үзэг, тэмдэглэлийн дэвтэр, хурц харандаа, эвтэйхэн хулгана, хэд хэдэн нэмэлт утас гэх мэт шаардлагатай бүх жижиг зүйлс гартаа байвал үнэхээр сайхан байдаг. Эдгээр үл анзаарагдам зүйлс хүмүүсийн анхаарлыг татахгүй, харин амьдралд тайтгарлыг нэмдэг. Үүнтэй ижил түүх нь янз бүрийн гар утасны болон ширээний програмуудын хувьд юм: урт дэлгэцийн агшин, зургийн хэмжээг багасгах, хувийн санхүү, толь бичиг, орчуулагч, хөрвүүлэгч гэх мэт. Танд нэг байгаа юу? VPS - аль нь хямдхан, үргэлж бэлэн байдаг, маш их ашиг авчирдаг вэ? Үгүй ээ, танай компанид байгаа нь биш, харин өөрийн гэсэн "халаасны". Бид 2019 онд жижиг VPS байхгүй бол лекц дээр ердийн усан оргилуур үзэггүйтэй адил гунигтай байна гэж бид бодсон. Яагаад гунигтай байх вэ? Зун боллоо. Зун яаж байна? Мэдээллийн технологийн мэргэжилтэнд зориулсан зун: гэртээ сууж, дуртай төслүүд дээрээ харамсахгүйгээр ажиллана. Ер нь бид бодож, хийсэн.

Тархи + VPS 30 рубль =?
Коммунизм ирлээ, нөхдүүд.

Тэр ийм л байна - манай VPS гучин

Бид 3-4 жилийн өмнө хямд VPS яагаад хэрэггүй болсон талаар бичсэн өрсөлдөгчид болон хэрэглэгчдийн олон нийтлэлийг уншсан. За, тийм ээ, тэгвэл VPS нь "цэнийн төлөө" цэвэр маркетинг байсан бөгөөд хэвийн ажиллах боломжийг санал болгож чадахгүй байв. Гэвч цаг хугацаа өөрчлөгдөж, виртуал нөөцийн өртөг улам бүр буурч, сард 30 рублийн хувьд бид үүнийг санал болгоход бэлэн байна.

  • Процессор: Intel Xeon 2 GHz (1 цөм)
  • Линукс систем (Debian, Ubuntu, CentOS сонгох боломжтой)
  • 1 зориулалтын IPv4 хаяг
  • Байгууллагын түвшний хурдан SSD хөтчүүд дээр 10 ГБ өгөгдөл хадгалах
  • RAM: 512 MB
  • Нэг секундын тооцоо
  • Хязгааргүй урсгал

Тариф нь техникийн нэмэлт хязгаарлалт, дэлгэрэнгүй мэдээлэлд хамаарна хуудас бидний гайхалтай санал - 30 рублийн VPS. 

Энэ виртуал сервер хэнд тохиромжтой вэ? Бараг бүх хүнд тийм: эхлэгчдэд, сонирхогчид, туршлагатай хөгжүүлэгчид, DIY фенүүд, тэр ч байтугай зарим компаниуд.

Энэ VPS юунд тохиромжтой вэ?

Хабрын уншигчид энэ тохиргоог ашиглах өөрийн гэсэн арга замыг олох нь гарцаагүй гэж бид бодож байна, гэхдээ бид өөрсдийн сонгосон санаануудыг цуглуулахаар шийдсэн - хэрэв хэн нэгэнд хэрэгтэй бол яах вэ, гэхдээ эрчүүд мэдэхгүй байна уу?

  • Энгийн вэбсайт, портфолио, кодтой анкет гэх мэтийг байрлуул. Мэдээжийн хэрэг, таны зохион бүтээсэн вэбсайт нь ажил олгогчдод эерэг сэтгэгдэл төрүүлдэг. Үүнийг өөрийн VPS дээр байрлуулж, сайтын аюулгүй байдал, тогтвортой байдлыг өөрөө хариуцаарай, харин байнгын хостинг үйлчилгээ үзүүлэгчийн ажилтнууд биш.
  • VPS-ийг боловсролын зорилгоор ашиглах: төслөө зохион байгуулах, сервер болон серверийн үйлдлийн системийн онцлогуудыг судлах, DNS-ийг туршиж үзэх, боловсролын жижиг сайттай танилцах.
  • Утасны хувьд. Заримдаа хувиараа бизнес эрхлэгч, фрилансер эсвэл маш жижиг компанид IP утас маш их хэрэгтэй байдаг бөгөөд энэ утасны операторууд маш их шуналтай байдаг. Энэ нь маш энгийн: бид серверээ авч, IP утасны оператороос дугаар худалдаж аваад, виртуал PBX байгуулж, дотоод дугаар үүсгэдэг (шаардлагатай бол). Хадгаламж нь асар их юм.
  • Програмаа шалгахын тулд серверийг ашиглана уу.
  • Ухаалаг гэрийн системийн мэдрэгчээс өгөгдлийг хянах, цуглуулах зэрэг DIY туршилт хийхэд серверийг ашиглаарай.
  • Үүнийг ашиглах ер бусын арга бол виртуал биржийн арилжааны туслах, арилжааны роботыг сервер дээр байрлуулах явдал юм. Та серверийн тогтвортой байдал, аюулгүй байдлыг бүрэн хариуцах бөгөөд энэ нь хөрөнгийн зах зээл дээр арилжаа хийх хяналттай хэрэгслийг хүлээн авах болно гэсэн үг юм. За ингээд сонирхож байгаа эсвэл төлөвлөж байгаа хүн байвал :)

Корпорацийн салбарт ийм VPS програмууд байдаг. Өмнө дурьдсан утасны үйлчилгээнээс гадна та хэд хэдэн сонирхолтой зүйлийг хэрэгжүүлж болно. Жишээлбэл:

  • Жижиг өгөгдлийн сан, мэдээллийг ftp ашиглан хол зайд байрлуул. Энэ нь танд шинэ аналитик, борлуулалтын хүмүүст зориулсан шинэчилсэн тохиргоо, танилцуулга гэх мэт маш хурдан солилцох боломжийг олгоно.
  • Програм хангамж эсвэл медиаг үзүүлэхийн тулд хэрэглэгчид эсвэл үйлчлүүлэгчдэд түр зуурын хандалт өгөх.

30 рублийн VPS туршилтын хөтөч - танд зориулж хийсэн

30 рубль бол маш бага тул та төлбөрөө төлж, шалгахын тулд карт авахыг хүсэхгүй байна. Бид ч гэсэн заримдаа залхуу байдаг ч энэ удаад бид чиний төлөө бүгдийг хийсэн. Серверүүдийг тулалдаанд оруулахын өмнө бид бүх нарийн ширийн зүйлийг шалгаж, энэ тарифаар серверүүд ямар чадвартай болохыг харуулах туршилт хийсэн. Үүнийг илүү сонирхолтой болгохын тулд бид хэт туйлшралыг нэмж, нягтрал ба ачаалал нь бидний тогтоосон утгаас хэтэрсэн тохиолдолд энэ тохиргоо хэрхэн ажиллахыг шалгасан. 

Хост нь процессор дээр янз бүрийн даалгавар гүйцэтгэж, дискний дэд системийг идэвхтэй ашигладаг хэд хэдэн виртуал машинуудын ачаалал дор байсан. Зорилго нь байлдааны үеийнхтэй харьцуулахуйц өндөр нягтрал, ачааллыг дуурайх явдал юм.

Тогтмол ачааллаас гадна бид sysbench ашиглан синтетик хэмжигдэхүүн цуглуулдаг 3 виртуал машин, дундаж үр дүнг доор өгөв, нэмэлт ачаалал үүсгэсэн 50 виртуал машин суурилуулсан. Туршилтын бүх виртуал машинууд ижил тохиргоотой (1 цөм, RAM 512 ГБ, SSD 10 ГБ), стандарт debian 9.6 дүрсийг үйлдлийн системээр сонгосон бөгөөд үүнийг RUVDS дээр хэрэглэгчдэд санал болгож байна.

Ачааллыг байлдааны байдалтай харьцуулж болохуйц шинж чанар, хэмжээгээр нь загварчилсан:

  • Зарим виртуал машинуудыг ачаалал багатай ажиллуулсан
  • Зарим машинууд процессор дээрх ачааллыг дуурайлган туршилтын скриптийг ажиллуулсан (хэрэгсэл стресс)
  • Виртуал машинуудын үлдсэн хэсэгт бид pv ашиглан тогтоосон хязгаартай урьдчилан бэлтгэсэн өгөгдлөөс диск рүү өгөгдлийг хуулахын тулд dd ашигладаг скриптийг ажиллуулсан (жишээг харж болно). энд и энд).

Мөн бидний санаж байгаагаар синтетик хэмжүүр цуглуулдаг гурван машин байсан.

Машин бүр дээр скриптийг 15 минут тутамд циклээр гүйцэтгэдэг байсан бөгөөд энэ нь процессор, санах ой, дискний стандарт sysbench тестийг явуулдаг.

Скрипт 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

Тохиромжтой болгох үүднээс үр дүнг sysbench форматаар танилцуулсан боловч туршилтын бүх хугацааны дундаж утгыг бүх машинаас авсан бөгөөд үр дүнг эндээс харж болно.

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

Үр дүн нь шинж чанартай боловч QoS гэж авч болохгүй. 

Нэмэлт ачаалал үүсгэдэг машинууд

Програм хангамж:

  • apt-get update
  • apt-get upgrade
  • apt-get python-pip суулгах
  • pip суулгах mysql-connector-python-rf

MariaDB суулгасан, Хэрхэн хийх вэ энд:

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

Туршилтын суурийг авсан Эндээс:

Өгөгдлийн санг тодорхойлсоны дагуу байрлуулна энд:

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

Жижиг туршилтын суурь:

Хүснэгт 

RowsCount 

Өгөгдлийн хэмжээ (МБ)

Индекс хэмжээ (KB)

хэлтэс 

9

0.02

16.00

хэлтэс 

331143 

11.52

5648.00

хэлтсийн_менежер 

24 

0.02

16.00

ажилчид 

299379 

14.52

0.00

цалин 

2838426 

95.63

0.00 

нэр 

442783 

19.56

0.00

Python дээр өвдөг дээрээ анхдагч тестийн үйлчилгээ бичигдсэн бөгөөд дөрвөн үйлдлийг гүйцэтгэдэг:

  1. getState: статусыг буцаана
  2. getEmployee: өгөгдлийн сангаас ажилчдыг (+цалин, цол хэргэм) буцаана
  3. patchEmployee: ажилчдын талбарыг өөрчлөх
  4. insertSalary: цалин оруулдаг

Үйлчилгээний эх сурвалж (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')

Анхаар Ямар ч тохиолдолд энэ үйлчилгээг жишээ, заавар болгон авч болохгүй!

Туршилтыг хуучин сайн JMeter ашиглан хийдэг. 15 минутаас 2 цаг хүртэл үргэлжилсэн цуврал туршилтуудыг эхлүүлсэн бөгөөд тасалдалгүй, хүсэлтийн хувь хэмжээ харилцан адилгүй, дамжуулах чадвар нь минутанд 300-600 хүсэлтийн хооронд хэлбэлзэж байв. 50-аас 500 хүртэлх утаснуудын тоо.

Өгөгдлийн сан маш бага тул тушаал:

mysql -e "SHOW ENGINE INNODB STATUS"

Үүнийг харуулж байна:

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

Хүсэлтэд хариу өгөх дундаж хугацааг доор харуулав.

Шошго

дундаж

Median

90% шугам

95% шугам

99% шугам

би

Макс

Ажилтан авах

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

нөхөөс ажилтан

161.42

83.29

308

492.57

1845.14

5

6639.4

цалин тавих

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Эдгээр синтетик үр дүнгээс энэхүү VPS нь таны тодорхой ажлуудад хэр тохиромжтой болохыг дүгнэхэд хэцүү байж магадгүй бөгөөд ерөнхийдөө жагсаасан аргууд нь бидний аль нэг хэлбэрээр шийдвэрлэх шаардлагатай тохиолдлуудад хязгаарлагддаг. Тиймээс бидний жагсаалт дараах байдалтай байна. бүрэн гүйцэд биш нь тодорхой. Бид таныг өөрийн бодит программууд болон даалгаврууд дээрээ дүгнэлт хийж, серверийг 30 рублиэр туршиж үзэхийг урьж байна, мөн энэ тохиргооны сонголтуудыг тайлбар дээр санал болгож байна.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх