1 TB/s хурдаар хайх

TL; DR: Дөрвөн жилийн өмнө би Google-ээс серверийн хяналтын шинэ хэрэгсэл гаргах санаатай явсан. Гол санаа нь ихэвчлэн тусгаарлагдсан функцуудыг нэг үйлчилгээнд нэгтгэх явдал байв цуглуулга бүртгэлийн шинжилгээ, хэмжүүр цуглуулах, сэрэмжлүүлэг болон хяналтын самбарууд. Нэг зарчим бол үйлчилгээ нь жинхэнэ байх ёстой хурдан, devops-ыг хялбар, интерактив, тааламжтай туршлагаар хангах. Энэ нь олон гигабайт өгөгдлийн багцыг секундын хэдэн хэсэгт багтаан төсөвт багтаан боловсруулах шаардлагатай. Бүртгэлийн менежментийн одоо байгаа хэрэгслүүд нь ихэвчлэн удаан бөгөөд барзгар байдаг тул хэрэглэгчдэд шинэ туршлага өгөх хэрэгслийг ухаалаг зохион бүтээх нь бидэнд маш сайн сорилттой тулгарсан.

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

Хуучин сургуулийн хүч

Бүртгэлийн шинжилгээ нь ихэвчлэн хайлтаас эхэлдэг: тодорхой загварт тохирсон бүх мессежийг ол. Scalyr-д эдгээр нь олон серверээс хэдэн арван эсвэл хэдэн зуун гигабайт лог юм. Орчин үеийн хандлага нь дүрмээр бол хайлтанд оновчтой болгосон зарим нарийн төвөгтэй өгөгдлийн бүтцийг бий болгодог. Би үүнийг Google-ээс харсан бөгөөд тэд энэ төрлийн зүйлд маш сайн байдаг. Гэхдээ бид илүү бүдүүлэг арга дээр тогтсон: логуудыг шугаман сканнердах. Энэ нь амжилттай болсон - бид өрсөлдөгчдөөсөө илүү хурдан хайлт хийх боломжтой интерфейсээр хангадаг (төгсгөлд нь хөдөлгөөнт дүрсийг үзнэ үү).

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

Энэ нийтлэлээс авсан гол санаанууд:

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

(Энэ нийтлэлд санах ойд өгөгдөл хайх талаар тайлбарласан болно. Ихэнх тохиолдолд хэрэглэгч лог хайлт хийх үед Scalyr серверүүд үүнийг аль хэдийн кэш болгосон байдаг. Дараагийн өгүүллээр кэшгүй лог хайх талаар ярилцах болно. Ижил зарчмууд: үр ашигтай код, бүдүүлэг хүч их хэмжээний тооцооллын нөөцтэй).

Харгис хүчний арга

Уламжлал ёсоор бол том өгөгдлийн багцыг түлхүүр үгийн индекс ашиглан хайдаг. Серверийн бүртгэлд хэрэглэх үед энэ нь лог дахь өвөрмөц үг бүрийг хайх гэсэн үг юм. Үг бүрийн хувьд та бүх оруулгуудын жагсаалтыг гаргах хэрэгтэй. Энэ нь 'error', 'firefox' эсвэл "transaction_16851951" гэх мэт энэ үгтэй бүх мессежийг олоход хялбар болгодог - зүгээр л индексийг хараарай.

Би энэ аргыг Google дээр ашигласан бөгөөд энэ нь сайн ажилласан. Гэхдээ Scalyr дээр бид логуудыг байтаар хайдаг.

Яагаад? Хийсвэр алгоритмын үүднээс авч үзвэл түлхүүр үгийн индексүүд нь харгис хүчээр хайлт хийхээс хамаагүй илүү үр дүнтэй байдаг. Гэсэн хэдий ч бид алгоритм зардаггүй, харин гүйцэтгэлийг зардаг. Гүйцэтгэл нь зөвхөн алгоритм төдийгүй системийн инженерчлэл юм. Бид бүх зүйлийг анхаарч үзэх ёстой: өгөгдлийн хэмжээ, хайлтын төрөл, боломжтой техник хангамж, програм хангамжийн контекст. Бидний тодорхой асуудалд "grep" гэх мэт зүйл нь индексээс илүү тохиромжтой гэж бид шийдсэн.

Индексүүд нь маш сайн боловч хязгаарлалттай байдаг. Нэг үг олоход амархан. Гэхдээ 'googlebot', '404' гэх мэт олон үгтэй мессеж хайх нь илүү хэцүү байдаг. "Баригдаагүй онцгой тохиолдол" гэх мэт хэллэгийг хайхад зөвхөн тухайн үгтэй бүх мессежийг төдийгүй тухайн үгийн байршлыг бүртгэдэг илүү төвөгтэй индекс шаардлагатай.

Жинхэнэ бэрхшээл нь үг хайхгүй байх үед ирдэг. Та роботуудаас хэр их ачаалал ирж байгааг харахыг хүсч байна гэж бодъё. Эхний бодол бол "bot" гэсэн үгийн бүртгэлээс хайх явдал юм. Ингэснээр та Googlebot, Bingbot болон бусад олон роботуудыг олох болно. Гэхдээ энд "бот" гэдэг нь үг биш, харин түүний нэг хэсэг юм. Хэрэв бид индексээс "bot" гэж хайвал "Googlebot" гэсэн үгтэй нийтлэл олдохгүй. Хэрэв та индекс дэх үг бүрийг шалгаад дараа нь олсон түлхүүр үгсийг хайж олоход хайлт ихээхэн удаашрах болно. Үүний үр дүнд зарим бүртгэлийн програмууд нь хэсэгчилсэн үг хайхыг зөвшөөрдөггүй эсвэл (хамгийн сайндаа) бага гүйцэтгэлтэй тусгай синтаксийг зөвшөөрдөг. Бид үүнээс зайлсхийхийг хүсч байна.

Өөр нэг асуудал бол цэг таслал юм. -аас ирсэн бүх хүсэлтийг олохыг хүсч байна уу 50.168.29.7? агуулсан логуудыг дибаг хийх талаар [error]? Доод үсэг нь ихэвчлэн цэг таслалыг алгасдаг.

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

Үүнээс гадна индексүүд цогцолбор. Мессеж бүрийг хэд хэдэн түлхүүр үгийн жагсаалтад нэмэх шаардлагатай. Эдгээр жагсаалтыг үргэлж хайхад хялбар хэлбэрээр хадгалах ёстой. Үг хэллэг, үг хэллэг эсвэл тогтмол хэллэг бүхий асуулгыг олон жагсаалтын үйлдлүүд болгон хөрвүүлж, үр дүнг сканнердаж, нэгтгэж үр дүнг гаргах шаардлагатай. Томоохон, олон түрээслэгчтэй үйлчилгээний хүрээнд энэхүү нарийн төвөгтэй байдал нь алгоритмуудыг шинжлэхэд харагдахгүй гүйцэтгэлийн асуудлуудыг үүсгэдэг.

Түлхүүр үгийн индексүүд нь маш их зай эзэлдэг бөгөөд хадгалалт нь бүртгэлийн удирдлагын системд томоохон зардал болдог.

Нөгөөтэйгүүр, хайлт бүр нь маш их тооцоолох хүчийг зарцуулдаг. Манай хэрэглэгчид өвөрмөц асуулгын өндөр хурдтай хайлтыг үнэлдэг ч ийм асуулга харьцангуй ховор хийгддэг. Ердийн хайлтын асуулгын хувьд, жишээлбэл, хяналтын самбарын хувьд бид тусгай арга техникийг ашигладаг (бид тэдгээрийг дараагийн өгүүллээр тайлбарлах болно). Бусад хүсэлтүүд маш ховор байдаг тул та нэг удаад нэгээс олон хүсэлтийг боловсруулах шаардлагагүй болно. Гэхдээ энэ нь манай серверүүд завгүй гэсэн үг биш юм: тэд шинэ мессеж хүлээн авах, дүн шинжилгээ хийх, шахах, сэрэмжлүүлгийг үнэлэх, хуучин өгөгдлийг шахах гэх мэт ажилд завгүй байна. Тиймээс бид асуулга гүйцэтгэхэд ашиглаж болох процессоруудын нэлээд их нөөцтэй байна.

Хэрэв танд хэрцгий асуудал (мөн маш их хүч) байгаа бол харгис хүч ажилладаг.

Brute force нь жижиг дотоод гогцоотой энгийн асуудлууд дээр хамгийн сайн ажилладаг. Ихэнхдээ та маш өндөр хурдтай ажиллахын тулд дотоод гогцоог оновчтой болгож чадна. Хэрэв код нь нарийн төвөгтэй бол түүнийг оновчтой болгох нь илүү хэцүү байдаг.

Манай хайлтын код анхандаа нэлээд том дотоод гогцоотой байсан. Бид хуудаснууд дээрх мессежийг 4K-ээр хадгалдаг; хуудас бүр нь зарим мессеж (UTF-8) болон мессеж бүрийн мета өгөгдлийг агуулдаг. Мета өгөгдөл нь утгын урт, дотоод мессежийн ID болон бусад талбаруудыг кодлодог бүтэц юм. Хайлтын мөчлөг дараах байдалтай байв.

1 TB/s хурдаар хайх

Энэ бол бодит кодын хялбаршуулсан хувилбар юм. Гэхдээ энд ч гэсэн олон объектын байршил, өгөгдлийн хуулбар, функцийн дуудлага харагдана. JVM нь функцийн дуудлагыг оновчтой болгох, түр зуурын объектуудыг хуваарилах тал дээр маш сайн байдаг тул энэ код биднээс илүү сайн ажилласан. Туршилтын явцад хэрэглэгчид үүнийг нэлээд амжилттай ашигласан. Гэвч эцэст нь бид үүнийг дараагийн шатанд авлаа.

(Бид яагаад шууд логтой ажиллахын оронд мессежийг 4K хуудас, текст болон мета өгөгдөлтэй энэ форматаар хадгалдаг вэ гэдгийг та асууж магадгүй. Дотооддоо Scalyr хөдөлгүүр нь мэдээллийн сан гэхээсээ илүү тархсан мэдээллийн сантай төстэй байдагтай холбоотой олон шалтгаан бий. файлын систем.Текст хайлтыг ихэвчлэн лог задлан шинжилсний дараа захын зайд DBMS маягийн шүүлтүүртэй хослуулдаг.Бид нэгэн зэрэг олон мянган лог хайх боломжтой ба энгийн текст файлууд нь манай гүйлгээний, хуулбарласан, түгээсэн өгөгдлийн менежментэд тохиромжгүй).

Эхэндээ ийм код нь харгис хүчний оновчлолд тийм ч тохиромжтой биш юм шиг санагдаж байв. "Жинхэнэ ажил"-д String.indexOf() CPU-ийн профайлд ч давамгайлсангүй. Өөрөөр хэлбэл, энэ аргыг дангаараа оновчтой болгох нь тийм ч их үр дүнд хүргэхгүй.

Бид хуудас бүрийн эхэнд мета өгөгдлийг хадгалдаг бөгөөд UTF-8 дахь бүх мессежийн текстийг нөгөө төгсгөлд байрлуулсан байдаг. Үүний давуу талыг ашиглан бид бүх хуудсыг нэг дор хайхын тулд давталтыг дахин бичсэн:

1 TB/s хурдаар хайх

Энэ хувилбар нь харагдац дээр шууд ажилладаг raw byte[] мөн 4K хуудсан дээрх бүх мессежийг нэг дор хайдаг.

Энэ нь харгис хүчний аргыг оновчтой болгоход илүү хялбар байдаг. Дотоод хайлтын гогцоо нь нийтлэл бүр дээр тус тусад нь биш харин бүхэл бүтэн 4K хуудсанд нэгэн зэрэг дуудагддаг. Өгөгдлийг хуулбарлах, объектын хуваарилалт байхгүй. Илүү төвөгтэй мета өгөгдлийн үйлдлүүдийг зөвхөн эерэг үр дүн гарсан тохиолдолд дууддаг бөгөөд мессеж болгон дээр биш. Ингэснээр бид нэг тонн нэмэлт ачааллыг арилгасан бөгөөд үлдсэн ачаа нь жижиг хайлтын системд төвлөрч, цаашдын оновчтой болгоход тохиромжтой.

Бидний бодит хайлтын алгоритм нь дээр суурилдаг Леонид Вольницкийн гайхалтай санаа. Энэ нь Бойер-Мурын алгоритмтай төстэй бөгөөд алхам бүрт хайлтын мөрийн уртыг алгасах болно. Гол ялгаа нь энэ нь нэг удаад хоёр байтыг шалгадаг бөгөөд энэ нь худал тохирохыг багасгах явдал юм.

Бидний хэрэгжүүлэлт нь хайлт бүрт 64К хайлтын хүснэгт үүсгэхийг шаарддаг боловч энэ нь бидний хайж буй гигабайт өгөгдөлтэй харьцуулахад юу ч биш юм. Дотоод гогцоо нь нэг цөм дээр секундэд хэд хэдэн гигабайт боловсруулдаг. Практикт тогтвортой гүйцэтгэл нь цөм тус бүр дээр секундэд 1,25 ГБ орчим байдаг бөгөөд сайжруулах боломж бий. Дотор давталтын гадна талын зарим хэсгийг арилгах боломжтой бөгөөд бид Java-ийн оронд C-ийн дотоод гогцоотой туршилт хийхээр төлөвлөж байна.

Бид хүч хэрэглэдэг

Лог хайлтыг "ойролцоогоор" хэрэгжүүлж болох талаар бид ярилцсан, гэхдээ бидэнд хэр их "хүч" байгаа вэ? Нилээд их.

1 цөм: Зөв ашиглавал орчин үеийн процессорын нэг цөм нь өөрөө маш хүчтэй байдаг.

8 цөм: Бид одоогоор Amazon hi1.4xlarge болон i2.4xlarge SSD серверүүд дээр ажиллаж байгаа бөгөөд тус бүр нь 8 цөмтэй (16 утас). Дээр дурьдсанчлан эдгээр цөмүүд нь ихэвчлэн далд үйл ажиллагаатай завгүй байдаг. Хэрэглэгч хайлт хийх үед арын үйлдлүүд түр зогссон бөгөөд хайлт хийхэд бүх 8 цөмийг чөлөөлнө. Хайлт нь ихэвчлэн секундын дотор дуусдаг бөгөөд үүний дараа арын ажил үргэлжилдэг (багасгах програм нь хайлтын асуулга нь арын чухал ажилд саад учруулахгүй байхыг баталгаажуулдаг).

16 цөм: найдвартай байдлын үүднээс бид серверүүдийг мастер/боол бүлэг болгон зохион байгуулдаг. Мастер бүр өөрийн удирдлага дор нэг SSD, нэг EBS сервертэй. Хэрэв үндсэн сервер гацвал SSD сервер тэр даруй байраа эзэлнэ. Бараг үргэлж мастер болон боол нь сайн ажилладаг тул өгөгдлийн блок бүрийг хоёр өөр сервер дээр хайх боломжтой (EBS slave сервер нь сул процессортой тул бид үүнийг тооцохгүй). Бид даалгаврыг хооронд нь хуваадаг бөгөөд ингэснээр бид нийт 16 цөмтэй болно.

Олон цөм: Ойрын ирээдүйд бид серверүүдээр мэдээлэл түгээх болно, ингэснээр тэд бүгд чухал биш хүсэлт бүрийг боловсруулахад оролцоно. Цөм бүр ажиллах болно. [Тэмдэглэл: Бид төлөвлөгөөг хэрэгжүүлж, хайлтын хурдыг 1 TB/s хүртэл нэмэгдүүлсэн, нийтлэлийн төгсгөлд байгаа тэмдэглэлийг үзнэ үү].

Энгийн байдал нь найдвартай байдлыг баталгаажуулдаг

Харгис хүчний аргын өөр нэг давуу тал нь түүний нэлээд тогтвортой гүйцэтгэл юм. Ерөнхийдөө хайлт нь асуудлын нарийн ширийн зүйл болон өгөгдлийн багцад тийм ч мэдрэмтгий байдаггүй (тийм учраас үүнийг "бүдүүн" гэж нэрлэдэг байх.

Түлхүүр үгийн индекс заримдаа гайхалтай хурдан үр дүнг гаргадаг бол зарим үед тийм биш байдаг. "Хэрэглэгчийн_50" гэсэн үг яг гурван удаа гарч ирдэг 5987235982 ГБ бүртгэлтэй гэж бодъё. Энэ нэр томъёоны хайлт нь индексээс шууд гурван байршлыг тоолох бөгөөд тэр даруй дуусгах болно. Гэхдээ нарийн төвөгтэй хайлт нь олон мянган түлхүүр үгсийг сканнердаж, удаан хугацаа шаарддаг.

Нөгөөтэйгүүр, харгис хүчээр хайлт нь ямар ч асуулгад ижил хурдтай явагддаг. Урт үг хайх нь илүү сайн, гэхдээ ганц тэмдэгт хайхад ч нэлээд хурдан байдаг.

Харгис хүчний аргын энгийн байдал нь түүний гүйцэтгэл нь онолын дээд цэгтээ ойрхон байна гэсэн үг юм. Дискний гэнэтийн ачаалал, түгжээний маргаан, заагч хөөцөлдөх болон бүтэлгүйтлийн олон мянган шалтгааны сонголтууд цөөн байдаг. Би өнгөрсөн долоо хоногт манай хамгийн ачаалалтай сервер дээр Scalyr хэрэглэгчдийн тавьсан хүсэлтийг харлаа. 14 мянган хүсэлт ирсэн. Тэдний яг найм нь нэг секундээс илүү хугацаа зарцуулсан; 000% нь 99 миллисекундын дотор дууссан (хэрэв та бүртгэлийн шинжилгээний хэрэглүүрийг ашиглаагүй бол надад итгээрэй: хурдан байна).

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

Үйлдлээр хайлт хийх

Энд Scalyr хайлтыг хэрхэн ашиглаж байгааг харуулсан богино хэмжээний хөдөлгөөнт дүрслэл байна. Бид олон нийтийн Github агуулах бүрт үйл явдал бүрийг импортлох демо данстай. Энэ үзүүлэн дээр би долоо хоногийн өгөгдлийг судалж байна: ойролцоогоор 600 MB түүхий лог.

Видеог миний ширээний компьютер дээр (серверээс 5000 км-ийн зайд) тусгай бэлтгэлгүйгээр шууд хийсэн. Таны харж буй гүйцэтгэл нь үүнээс ихээхэн шалтгаална вэб үйлчлүүлэгчийн оновчлол, түүнчлэн хурдан бөгөөд найдвартай backend. "Ачаалах" үзүүлэлтгүй зогсолт хийх бүрт би түр зогсоодог тул та миний дарах гэж буй зүйлийг унших боломжтой.

1 TB/s хурдаар хайх

Эцэст нь хэлэхэд

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

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

Харгис хүчний аргыг ашиглан бид хэд хэдэн бүртгэлээс хурдан, найдвартай, уян хатан хайлт хийсэн. Эдгээр санаанууд таны төслүүдэд хэрэг болно гэж найдаж байна.

Засварлах: Сүүлийн хэдэн жилийн гүйцэтгэлийн өсөлтийг тусгахын тулд гарчиг болон бичвэрийг "Секундэд 20 ГБ хурдтай хайх" гэснийг "Секундэд 1 ТБ хурдтай хайх" болгон өөрчилсөн. Хурдны энэхүү өсөлт нь юуны түрүүнд бидний үйлчлүүлэгчдийн баазыг нэмэгдүүлэх зорилгоор өнөөдөр тавьж буй EC2 серверүүдийн төрөл, тоо өөрчлөгдсөнтэй холбоотой юм. Үйл ажиллагааны үр ашгийг нэмэгдүүлэх өөр нэг өөрчлөлтүүд удахгүй гарах бөгөөд бид тэдгээрийг хуваалцахыг тэсэн ядан хүлээж байна.

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

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