CEPH-тэй ажиллаж байсан туршлагатай

Нэг дискэнд багтаахаас илүү өгөгдөл байгаа бол RAID-ийн талаар бодох цаг болжээ. Хүүхэд байхдаа би ахмадуудаасаа "Нэг л өдөр RAID өнгөрсөн зүйл болж, объектын хадгалалт дэлхийг дүүргэх болно, чи CEPH гэж юу байдгийг ч мэдэхгүй" гэж байнга сонсдог байсан тул миний бие даасан амьдралын хамгийн эхний зүйл өөрийн кластерийг бий болгох байсан. Туршилтын зорилго нь цефийн дотоод бүтэцтэй танилцах, түүний хэрэглээний хамрах хүрээг ойлгох явдал байв. Дунд болон жижиг бизнесүүдэд ceph-ийг хэрэгжүүлэх нь хэр үндэслэлтэй вэ? Хэдэн жил ажилласны дараа хэд хэдэн нөхөж баршгүй мэдээлэл алдагдсаны дараа бүх зүйл тийм ч хялбар биш гэдгийг ойлгосон. CEPH-ийн онцлог нь түүнийг өргөнөөр нэвтрүүлэхэд саад тотгор учруулдаг бөгөөд үүнээс болж туршилтууд мухардалд оров. Хийсэн бүх арга хэмжээ, олж авсан үр дүн, гаргасан дүгнэлтийг доор харуулав. Мэдлэгтэй хүмүүс туршлагаа хуваалцаж, зарим зүйлийг тайлбарлавал би талархах болно.

Тайлбар: Сэтгэгдэл бичсэн хүмүүс нийтлэлийг бүхэлд нь хянан үзэх шаардлагатай зарим таамаглалд ноцтой алдаа байгааг илрүүлсэн.

CEPH стратеги

CEPH кластер нь дурын хэмжээтэй, дурын тооны K дискүүдийг нэгтгэж, тэдгээрт өгөгдөл хадгалдаг бөгөөд хэсэг бүрийг (анхдагчаар 4 МБ) өгөгдсөн тоог N дахин хуулбарладаг.

Хоёр ижил дисктэй хамгийн энгийн тохиолдлыг авч үзье. Тэдгээрээс та RAID 1 эсвэл N=2 кластер угсарч болно - үр дүн нь ижил байх болно. Хэрэв гурван диск байгаа бөгөөд тэдгээр нь өөр өөр хэмжээтэй байвал N=2-тэй кластер угсарч болно: зарим өгөгдөл нь 1 ба 2-р диск дээр, зарим нь 1 ба 3-р дискэн дээр байх болно. 2 ба 3 дээр, харин RAID байхгүй (та ийм RAID угсарч болно, гэхдээ энэ нь гажуудал болно). Хэрэв илүү олон диск байгаа бол RAID 5 үүсгэх боломжтой; CEPH нь аналог - erasure_code-тэй бөгөөд энэ нь хөгжүүлэгчдийн анхны үзэл баримтлалтай зөрчилддөг тул үүнийг авч үзэхгүй. RAID 5 нь цөөхөн тооны хөтчүүд байгаа гэж үздэг бөгөөд тэдгээр нь бүгд сайн нөхцөлд байна. Хэрэв нэг нь бүтэлгүйтвэл бусад нь дискийг сольж, өгөгдлийг сэргээх хүртэл хүлээх ёстой. N>=3-тэй CEPH нь хуучин дискийг ашиглахыг дэмждэг, ялангуяа хэрэв та нэг хуулбарыг өгөгдөл хадгалахын тулд хэд хэдэн сайн диск хадгалдаг бол үлдсэн хоёр, гурван хувийг олон тооны хуучин дискэн дээр хадгалдаг бол мэдээлэл аюулгүй байх болно, учир нь одоохондоо шинэ дискүүд амьд байгаа тул ямар ч асуудал гарахгүй бөгөөд хэрэв тэдгээрийн аль нэг нь эвдэрсэн бол таван жилээс дээш хугацаатай гурван диск, өөр өөр серверүүдээс нэгэн зэрэг эвдрэх магадлал маш бага юм. үйл явдал.

Хуулбар тараахад нарийн зүйл бий. Анхдагч байдлаар, өгөгдөл нь илүү олон (диск тутамд ~ 100) PG түгээлтийн бүлгүүдэд хуваагддаг гэж үздэг бөгөөд тэдгээр нь тус бүр нь зарим дискэн дээр хуулбарлагддаг. K=6, N=2 гэж бодъё, тэгвэл аль нэг хоёр диск бүтэлгүйтвэл өгөгдөл алдагдах баталгаатай, учир нь магадлалын онолын дагуу эдгээр хоёр дискэн дээр дор хаяж нэг PG байрлана. Мөн нэг бүлгийн алдагдал нь усан сан дахь бүх өгөгдлийг ашиглах боломжгүй болгодог. Хэрэв дискүүдийг гурван хос болгон хувааж, өгөгдлийг зөвхөн нэг хос доторх дискэн дээр хадгалахыг зөвшөөрдөг бол ийм хуваарилалт нь аль нэг дискний эвдрэлд тэсвэртэй боловч хоёр диск эвдэрсэн тохиолдолд өгөгдөл алдагдах магадлал бага байна. 100%, гэхдээ зөвхөн 3/15, тэр ч байтугай эвдэрсэн тохиолдолд гурван диск - зөвхөн 12/20. Тиймээс өгөгдөл түгээх энтропи нь алдааг тэсвэрлэх чадварт нөлөөлдөггүй. Файл серверийн хувьд үнэгүй RAM нь хариу өгөх хурдыг ихээхэн нэмэгдүүлдэг гэдгийг анхаарна уу. Зангилаа бүрт илүү их санах ой, бүх зангилаанд илүү их санах ой байх тусам хурдан байх болно. Энэ нь кластерын нэг серверээс илүү давуу тал бөгөөд үүнээс ч илүүтэйгээр маш бага хэмжээний санах ой суурилуулсан техник хангамжийн NAS юм.

Үүнээс үзэхэд CEPH нь хуучирсан тоног төхөөрөмжөөс хамгийн бага хөрөнгө оруулалт хийх чадвартай, хэдэн арван сүрьеэгийн найдвартай өгөгдөл хадгалах системийг бий болгох сайн арга юм (энд мэдээж зардал шаардагдах боловч арилжааны хадгалалтын системтэй харьцуулахад бага байх болно).

Кластерын хэрэгжилт

Туршилтын хувьд ашиглалтаас хасагдсан компьютер Intel DQ57TM + Intel core i3 540 + 16 ГБ RAM-г авч үзье. Бид дөрвөн 2 TB дискийг RAID10 шиг зохион байгуулах бөгөөд амжилттай туршилт хийсний дараа бид хоёр дахь зангилаа болон ижил тооны диск нэмнэ.

Линукс суулгаж байна. Түгээлт нь өөрчлөх, тогтвортой байх чадварыг шаарддаг. Debian болон Suse нь шаардлагад нийцдэг. Suse нь ямар ч багцыг идэвхгүй болгох боломжийг олгодог илүү уян хатан суулгагчтай; Харамсалтай нь системийг гэмтээхгүйгээр алийг нь хаяж болохыг би олж чадаагүй. Debootstrap buster ашиглан Debian суулгана уу. Min-base сонголт нь драйвергүй эвдэрсэн системийг суулгадаг. Бүрэн хувилбартай харьцуулахад хэмжээний ялгаа нь тийм ч том биш юм. Ажил нь физик машин дээр хийгддэг тул би виртуал машинууд шиг агшин зуурын зураг авахыг хүсч байна. Энэ сонголтыг LVM эсвэл btrfs (эсвэл xfs, эсвэл zfs - ялгаа нь тийм ч их биш) өгдөг. LVM агшин зуурын зураг нь хүчтэй цэг биш юм. btrfs суулгана уу. Мөн ачаалагч нь MBR-д байна. 50 МБ дискийг FAT хуваалттай 1 МБ хуваалтын хүснэгтийн талбарт шахаж, системд бүх зайг хуваарилах нь утгагүй юм. Диск дээр 700 MB багтаамжтай. SUSE-ийн үндсэн суулгац хэр их байгааг би санахгүй байна, энэ нь ойролцоогоор 1.1 эсвэл 1.4 ГБ байх гэж бодож байна.

CEPH суулгана уу. Бид debian репозиторийн 12 хувилбарыг үл тоомсорлож, 15.2.3 сайтаас шууд холбогддог. Бид "CEPH-г гараар суулгах" хэсгийн зааврыг дагаж дараах анхааруулгатай байна.

  • Репозиторыг холбохын өмнө та gnupg wget ca-сертификатуудыг суулгах ёстой
  • Хадгалах газрыг холбосны дараа, гэхдээ кластер суулгахын өмнө багцуудыг суулгахыг орхигдуулсан: apt -y --no-install-recommends install ceph-common ceph-mon ceph-osd ceph-mds ceph-mgr
  • CEPH суулгах үед тодорхойгүй шалтгаанаар lvm2 суулгахыг оролдох болно. Зарчмын хувьд энэ нь харамсалтай биш, гэхдээ суулгалт амжилтгүй болсон тул CEPH ч суулгахгүй.

    Энэ нөхөөс нь тусалсан:

    cat << EOF >> /var/lib/dpkg/status
    Package: lvm2
    Status: install ok installed
    Priority: important
    Section: admin
    Installed-Size: 0
    Maintainer: Debian Adduser Developers <[email protected]>
    Architecture: all
    Multi-Arch: foreign
    Version: 113.118
    Description: No-install
    EOF
    

Кластерын тойм

ceph-osd - дискэн дээрх өгөгдлийг хадгалах үүрэгтэй. Диск бүрийн хувьд объект руу унших, бичих хүсэлтийг хүлээн авч, гүйцэтгэдэг сүлжээний үйлчилгээг эхлүүлдэг. Диск дээр хоёр хуваалт үүсдэг. Тэдгээрийн нэг нь кластер, дискний дугаар, кластерын түлхүүрүүдийн талаархи мэдээллийг агуулдаг. Энэхүү 1KB мэдээлэл нь диск нэмэхэд нэг удаа үүсдэг бөгөөд хэзээ ч өөрчлөгддөггүй. Хоёрдахь хуваалт нь файлын системгүй бөгөөд CEPH хоёртын өгөгдлийг хадгалдаг. Өмнөх хувилбаруудын автомат суурилуулалт нь үйлчилгээний мэдээллийн 100MB xfs хуваалтыг үүсгэсэн. Би дискийг MBR болгон хөрвүүлж, зөвхөн 16MB хуваарилсан - үйлчилгээ нь гомдоллодоггүй. Миний бодлоор xfs-г ямар ч асуудалгүйгээр ext-ээр сольж болно. Энэ хуваалт нь /var/lib/…-д суурилагдсан бөгөөд үйлчилгээ нь OSD-ийн талаарх мэдээллийг уншиж, мөн хоёртын өгөгдөл хадгалагдаж буй блок төхөөрөмжийн лавлагааг олдог. Онолын хувьд та /var/lib/…-д туслах файлуудыг нэн даруй байрлуулж, өгөгдөлд зориулж бүх дискийг хуваарилж болно. Ceph-deploy-ээр дамжуулан OSD үүсгэх үед /var/lib/… дотор хуваалтыг холбох дүрэм автоматаар үүсгэгдэх ба ceph хэрэглэгч хүссэн блок төхөөрөмжийг унших эрхийг мөн олгодог. Хэрэв та гараар суулгасан бол үүнийг өөрөө хийх ёстой, баримт бичигт үүнийг заагаагүй болно. Мөн хангалттай физик санах ойтой байхын тулд osd санах ойн зорилтот параметрийг зааж өгөхийг зөвлөж байна.

ceph-mds. Доод түвшинд CEPH нь объектын хадгалалт юм. Хадгалах санг хаах чадвар нь 4MB блок бүрийг объект болгон хадгалахад хүргэдэг. Файл хадгалах нь ижил зарчмаар ажилладаг. Хоёр сан үүсгэсэн: нэг нь мета өгөгдөлд, нөгөө нь өгөгдөлд зориулагдсан. Тэдгээрийг файлын системд нэгтгэдэг. Энэ мөчид ямар нэгэн бичлэг үүссэн тул хэрэв та файлын системийг устгасан ч хоёр санг хоёуланг нь хадгалсан бол үүнийг сэргээх боломжгүй болно. Файлуудыг блокоор задлах журам байдаг, би үүнийг туршиж үзээгүй. Ceph-mds үйлчилгээ нь файлын системд хандах үүрэгтэй. Файлын систем бүр үйлчилгээний тусдаа жишээг шаарддаг. Хэд хэдэн файлын системийг нэг дор үүсгэх боломжийг олгодог "индекс" сонголт байдаг - бас туршиж үзээгүй.

Ceph-mon - Энэ үйлчилгээ нь кластерын газрын зургийг хадгалдаг. Үүнд бүх OSD-ийн талаарх мэдээлэл, PG-г OSD-д түгээх алгоритм, хамгийн чухал нь бүх объектын талаарх мэдээлэл (энэ механизмын дэлгэрэнгүй мэдээлэл надад тодорхойгүй байна: /var/lib/ceph/mon/…/ лавлах байдаг. store.db, энэ нь 26MB хэмжээтэй том файл агуулдаг бөгөөд 105K объектын кластерт нэг объект бүрт 256 байтаас арай илүү хэмжээтэй байдаг - Миний бодлоор монитор нь бүх объектын жагсаалт болон PG-ийн жагсаалтыг хадгалдаг гэж би бодож байна. тэдгээр нь байрладаг). Энэ лавлахыг гэмтээх нь кластер дахь бүх өгөгдөл алдагдахад хүргэдэг. Эндээс CRUSH нь PG-г OSD дээр, мөн PG дээр объектууд хэрхэн байрлаж байгааг харуулдаг - хөгжүүлэгчид энэ үгнээс хэчнээн зайлсхийсэн ч мэдээллийн санд төвлөрсөн байдлаар хадгалагддаг гэсэн дүгнэлтэд хүрсэн. Үүний үр дүнд, нэгдүгээрт, бид системийг флаш диск дээр RO горимд суулгаж чадахгүй, учир нь мэдээллийн сан байнга бүртгэгддэг тул эдгээрт нэмэлт диск шаардлагатай (бараг 1 ГБ-аас ихгүй), хоёрдугаарт, шаардлагатай байна. энэ суурийг бодит цаг хугацаанд хуулах. Хэрэв хэд хэдэн монитор байгаа бол алдааны хүлцэл автоматаар хангагдана, гэхдээ манай тохиолдолд зөвхөн нэг монитор, дээд тал нь хоёр байна. OSD өгөгдөл дээр үндэслэн мониторыг сэргээх онолын журам байдаг, би янз бүрийн шалтгааны улмаас гурван удаа хандсан бөгөөд гурван удаа алдааны мэдэгдэл, өгөгдөл байхгүй байсан. Харамсалтай нь энэ механизм ажиллахгүй байна. Бид OSD дээр бяцхан хуваалт ажиллуулж, мэдээллийн баазыг хадгалахын тулд RAID угсардаг бөгөөд энэ нь гүйцэтгэлд маш муугаар нөлөөлнө, эсвэл портуудыг эзлэхгүйн тулд дор хаяж хоёр найдвартай физик зөөвөрлөгч, болж өгвөл USB хуваарилдаг.

rados-gw - S3 протокол болон үүнтэй төстэй зүйлсээр дамжуулан объектын хадгалалтыг экспортлодог. Олон усан санг бий болгодог, яагаад гэдэг нь тодорхойгүй байна. Би нэг их туршилт хийгээгүй.

ceph-mgr - Энэ үйлчилгээг суулгахдаа хэд хэдэн модулийг ажиллуулдаг. Тэдний нэг нь автомат масштабтай бөгөөд үүнийг идэвхгүй болгох боломжгүй юм. Энэ нь PG/OSD-ийн зөв хэмжээг хадгалахыг хичээдэг. Хэрэв та харьцааг гараар хянахыг хүсвэл сан тус бүрийн масштабыг идэвхгүй болгож болно, гэхдээ энэ тохиолдолд модуль 0-д хуваагдаж гацах ба кластерийн байдал ERROR болно. Модуль нь Python дээр бичигдсэн бөгөөд хэрэв та шаардлагатай мөрийг тайлбарлавал энэ нь түүнийг идэвхгүй болгоход хүргэдэг. Нарийвчилсан мэдээллийг санахад хэтэрхий залхуу байна.

Ашигласан эх сурвалжуудын жагсаалт:

CEPH суурилуулах
Мониторын бүрэн доголдлоос сэргэлт

Скриптийн жагсаалт:

Системийг debootstrap-ээр суулгаж байна

blkdev=sdb1
mkfs.btrfs -f /dev/$blkdev
mount /dev/$blkdev /mnt
cd /mnt
for i in {@,@var,@home}; do btrfs subvolume create $i; done
mkdir snapshot @/{var,home}
for i in {var,home}; do mount -o bind @${i} @/$i; done
debootstrap buster @ http://deb.debian.org/debian; echo $?
for i in {dev,proc,sys}; do mount -o bind /$i @/$i; done
cp /etc/bash.bashrc @/etc/

chroot /mnt/@ /bin/bash
echo rbd1 > /etc/hostname
passwd
uuid=`blkid | grep $blkdev | cut -d """ -f 2`
cat << EOF > /etc/fstab
UUID=$uuid / btrfs noatime,nodiratime,subvol=@ 0 1
UUID=$uuid /var btrfs noatime,nodiratime,subvol=@var 0 2
UUID=$uuid /home btrfs noatime,nodiratime,subvol=@home 0 2
EOF
cat << EOF >> /var/lib/dpkg/status
Package: lvm2
Status: install ok installed
Priority: important
Section: admin
Installed-Size: 0
Maintainer: Debian Adduser Developers <[email protected]>
Architecture: all
Multi-Arch: foreign
Version: 113.118
Description: No-install

Package: sudo
Status: install ok installed
Priority: important
Section: admin
Installed-Size: 0
Maintainer: Debian Adduser Developers <[email protected]>
Architecture: all
Multi-Arch: foreign
Version: 113.118
Description: No-install
EOF

exit
grub-install --boot-directory=@/boot/ /dev/$blkdev
init 6

apt -yq install --no-install-recommends linux-image-amd64 bash-completion ed btrfs-progs grub-pc iproute2 ssh  smartmontools ntfs-3g net-tools man
exit
grub-install --boot-directory=@/boot/ /dev/$blkdev
init 6

Кластер үүсгэх

apt -yq install --no-install-recommends gnupg wget ca-certificates
echo 'deb https://download.ceph.com/debian-octopus/ buster main' >> /etc/apt/sources.list
wget -q -O- 'https://download.ceph.com/keys/release.asc' | apt-key add -
apt update
apt -yq install --no-install-recommends ceph-common ceph-mon

echo 192.168.11.11 rbd1 >> /etc/hosts
uuid=`cat /proc/sys/kernel/random/uuid`
cat << EOF > /etc/ceph/ceph.conf
[global]
fsid = $uuid
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
mon allow pool delete = true
mon host = 192.168.11.11
mon initial members = rbd1
mon max pg per osd = 385
osd crush update on start = false
#osd memory target = 2147483648
osd memory target = 1610612736
osd scrub chunk min = 1
osd scrub chunk max = 2
osd scrub sleep = .2
osd pool default pg autoscale mode = off
osd pool default size = 1
osd pool default min size = 1
osd pool default pg num = 1
osd pool default pgp num = 1
[mon]
mgr initial modules = dashboard
EOF

ceph-authtool --create-keyring ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'
ceph-authtool --create-keyring ceph.client.admin.keyring --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'
cp ceph.client.admin.keyring /etc/ceph/
ceph-authtool --create-keyring bootstrap-osd.ceph.keyring --gen-key -n client.bootstrap-osd --cap mon 'profile bootstrap-osd' --cap mgr 'allow r'
cp bootstrap-osd.ceph.keyring /var/lib/ceph/bootstrap-osd/ceph.keyring
ceph-authtool ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring
ceph-authtool ceph.mon.keyring --import-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring
monmaptool --create --add rbd1 192.168.11.11 --fsid $uuid monmap
rm -R /var/lib/ceph/mon/ceph-rbd1/*
ceph-mon --mkfs -i rbd1 --monmap monmap --keyring ceph.mon.keyring
chown ceph:ceph -R /var/lib/ceph
systemctl enable ceph-mon@rbd1
systemctl start ceph-mon@rbd1
ceph mon enable-msgr2
ceph status

# dashboard

apt -yq install --no-install-recommends ceph-mgr ceph-mgr-dashboard python3-distutils python3-yaml
mkdir /var/lib/ceph/mgr/ceph-rbd1
ceph auth get-or-create mgr.rbd1 mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-rbd1/keyring
systemctl enable ceph-mgr@rbd1
systemctl start ceph-mgr@rbd1
ceph config set mgr mgr/dashboard/ssl false
ceph config set mgr mgr/dashboard/server_port 7000
ceph dashboard ac-user-create root 1111115 administrator
systemctl stop ceph-mgr@rbd1
systemctl start ceph-mgr@rbd1

OSD (хэсэг) нэмэх

apt install ceph-osd

osdnum=`ceph osd create`
mkdir -p /var/lib/ceph/osd/ceph-$osdnum
mkfs -t xfs /dev/sda1
mount -t xfs /dev/sda1 /var/lib/ceph/osd/ceph-$osdnum
cd /var/lib/ceph/osd/ceph-$osdnum
ceph auth get-or-create osd.0 mon 'profile osd' mgr 'profile osd' osd 'allow *' > /var/lib/ceph/osd/ceph-$osdnum/keyring
ln -s /dev/disk/by-partuuid/d8cc3da6-02  block
ceph-osd -i $osdnum --mkfs
#chown ceph:ceph /dev/sd?2
chown ceph:ceph -R /var/lib/ceph
systemctl enable ceph-osd@$osdnum
systemctl start ceph-osd@$osdnum

Хураангуй

CEPH-ийн маркетингийн гол давуу тал нь CRUSH - өгөгдлийн байршлыг тооцоолох алгоритм юм. Мониторууд энэ алгоритмыг үйлчлүүлэгчдэд түгээдэг бөгөөд үүний дараа үйлчлүүлэгчид хүссэн зангилаа болон хүссэн OSD-ийг шууд хүсдэг. CRUSH нь төвлөрөл байхгүйг баталгаажуулдаг. Энэ нь хэвлээд хананд өлгөх боломжтой жижиг файл юм. Дадлага нь CRUSH бол бүрэн хэмжээний газрын зураг биш гэдгийг харуулсан. Хэрэв та бүх OSD болон CRUSH-ыг хадгалан мониторуудыг устгаад дахин бүтээвэл кластерыг сэргээхэд хангалтгүй юм. Үүнээс үзэхэд монитор бүр бүхэл бүтэн кластерын талаархи зарим мета өгөгдлийг хадгалдаг гэсэн дүгнэлтэд хүрсэн. Энэхүү мета өгөгдлийн бага хэмжээ нь кластерын хэмжээнд хязгаарлалт тавьдаггүй боловч тэдгээрийн аюулгүй байдлыг хангах шаардлагатай бөгөөд энэ нь системийг флаш диск дээр суулгаснаар дискний хэмнэлтийг арилгаж, гурваас бага зангилаатай кластеруудыг оруулаагүй болно. Нэмэлт функцүүдийн талаархи хөгжүүлэгчийн түрэмгий бодлого. Минимализмаас хол. Баримт бичиг нь "Бидэнд байгаа зүйлд баярлалаа, гэхдээ энэ нь маш бага байна." Үйлчилгээнүүдтэй бага түвшинд харилцах боломжоор хангагдсан боловч баримт бичиг нь энэ сэдвийг хэтэрхий өнгөцхөн хөндсөн тул тиймээс үгүй ​​гэсэн магадлал өндөр байна. Онцгой байдлын үед өгөгдлийг сэргээх боломж бараг байхгүй.

Цаашдын арга хэмжээ авах сонголтууд: CEPH-ээс татгалзаж, олон дискний btrfs (эсвэл xfs, zfs) ашиглах, CEPH-ийн тухай шинэ мэдээлэл олж авах, энэ нь танд үүнийг заасан нөхцөлд ажиллуулах боломжийг олгоно, өөрийн санах ойг дэвшилтэт хэлбэрээр бичихийг хичээ. сургалт.

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

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