ខ្ញុំស្នើឱ្យអ្នកអានប្រតិចារិកនៃរបាយការណ៍ចុងឆ្នាំ 2019 ដោយ Alexander Valyalkin "Go optimizations in VictoriaMetrics"
នេះជាតំណភ្ជាប់ទៅកាន់វីដេអូនៃរបាយការណ៍នេះ -
ប្រាប់យើងអំពីខ្លួនអ្នក។ ខ្ញុំគឺ Alexander Valyalkin ។ នៅទីនេះ fast
ឬជាមួយ quick
បុព្វបទ។
បច្ចុប្បន្នខ្ញុំកំពុងធ្វើការលើ VictoriaMetrics។ តើវាជាអ្វី ហើយតើខ្ញុំកំពុងធ្វើអ្វីនៅទីនោះ? ខ្ញុំនឹងនិយាយអំពីរឿងនេះនៅក្នុងបទបង្ហាញនេះ។
ខ្លឹមសារនៃរបាយការណ៍មានដូចខាងក្រោម៖
- ដំបូងខ្ញុំនឹងប្រាប់អ្នកពីអ្វីដែល VictoriaMetrics ។
- បន្ទាប់មកខ្ញុំនឹងប្រាប់អ្នកពីស៊េរីពេលវេលា។
- បន្ទាប់មកខ្ញុំនឹងប្រាប់អ្នកពីរបៀបដែលមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលាដំណើរការ។
- បន្ទាប់ ខ្ញុំនឹងប្រាប់អ្នកអំពីស្ថាបត្យកម្មមូលដ្ឋានទិន្នន័យ៖ តើវាមានអ្វីខ្លះ។
- ហើយបន្ទាប់មកបន្តទៅការបង្កើនប្រសិទ្ធភាពដែល VictoriaMetrics មាន។ នេះគឺជាការបង្កើនប្រសិទ្ធភាពសម្រាប់សន្ទស្សន៍បញ្ច្រាស និងការបង្កើនប្រសិទ្ធភាពសម្រាប់ការអនុវត្ត bitset នៅក្នុង Go ។
តើមាននរណាម្នាក់ក្នុងចំណោមទស្សនិកជនស្គាល់ថាអ្វីជា VictoriaMetrics? អីយ៉ា មនុស្សជាច្រើនបានដឹងហើយ។ វាជាដំណឹងល្អ។ សម្រាប់អ្នកដែលមិនដឹងនេះគឺជាមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលា។ វាត្រូវបានផ្អែកលើស្ថាបត្យកម្ម ClickHouse លើព័ត៌មានលម្អិតមួយចំនួននៃការអនុវត្ត ClickHouse ។ ឧទាហរណ៍ ដូចជា៖ MergeTree ការគណនាប៉ារ៉ាឡែលលើស្នូលដំណើរការដែលមានទាំងអស់ និងការបង្កើនប្រសិទ្ធភាពប្រតិបត្តិការដោយធ្វើការលើប្លុកទិន្នន័យដែលត្រូវបានដាក់ក្នុងឃ្លាំងសម្ងាត់របស់ខួរក្បាល។
VictoriaMetrics ផ្តល់នូវការបង្ហាប់ទិន្នន័យល្អប្រសើរជាងមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលាផ្សេងទៀត។
វាធ្វើមាត្រដ្ឋានបញ្ឈរ - នោះគឺអ្នកអាចបន្ថែមដំណើរការបន្ថែម RAM កាន់តែច្រើននៅលើកុំព្យូទ័រមួយ។ VictoriaMetrics នឹងប្រើប្រាស់ធនធានដែលមានទាំងនេះដោយជោគជ័យ ហើយនឹងបង្កើនផលិតភាពលីនេអ៊ែរ។
VictoriaMetrics ក៏ធ្វើមាត្រដ្ឋានផ្ដេកផងដែរ - នោះគឺអ្នកអាចបន្ថែមថ្នាំងបន្ថែមទៅចង្កោម VictoriaMetrics ហើយដំណើរការរបស់វានឹងកើនឡើងស្ទើរតែលីនេអ៊ែរ។
ដូចដែលអ្នកបានទាយ VictoriaMetrics គឺជាមូលដ្ឋានទិន្នន័យលឿន ព្រោះខ្ញុំមិនអាចសរសេរអ្នកដទៃបានទេ។ ហើយវាត្រូវបានសរសេរនៅក្នុង Go ដូច្នេះខ្ញុំកំពុងនិយាយអំពីវានៅឯកិច្ចប្រជុំនេះ។
តើអ្នកណាដឹងថាស៊េរីពេលវេលាគឺជាអ្វី? គាត់ក៏ស្គាល់មនុស្សជាច្រើនផងដែរ។ ស៊េរីពេលវេលាគឺជាស៊េរីនៃគូ (timestamp, значение)
ដែលជាកន្លែងដែលគូទាំងនេះត្រូវបានតម្រៀបតាមពេលវេលា។ តម្លៃគឺជាលេខចំណុចអណ្តែត - float64 ។
ស៊េរីពេលវេលានីមួយៗត្រូវបានកំណត់អត្តសញ្ញាណដោយកូនសោ។ តើគន្លឹះនេះរួមបញ្ចូលអ្វីខ្លះ? វាមានសំណុំមិនទទេនៃគូតម្លៃគន្លឹះ។
នេះគឺជាឧទាហរណ៍នៃស៊េរីពេលវេលា។ គន្លឹះនៃស៊េរីនេះគឺជាបញ្ជីគូ៖ __name__="cpu_usage"
គឺជាឈ្មោះរបស់ម៉ែត្រ instance="my-server"
- នេះគឺជាកុំព្យូទ័រដែលម៉ែត្រនេះត្រូវបានប្រមូល datacenter="us-east"
- នេះគឺជាមជ្ឈមណ្ឌលទិន្នន័យដែលកុំព្យូទ័រនេះស្ថិតនៅ។
យើងបានបញ្ចប់ជាមួយនឹងឈ្មោះស៊េរីពេលវេលាដែលមានគូតម្លៃសំខាន់ៗចំនួនបី។ គន្លឹះនេះត្រូវគ្នាទៅនឹងបញ្ជីនៃគូ (timestamp, value)
. t1, t3, t3, ..., tN
- ទាំងនេះគឺជាត្រាពេលវេលា, 10, 20, 12, ..., 15
- តម្លៃដែលត្រូវគ្នា។ នេះជាការប្រើ cpu នៅពេលកំណត់សម្រាប់ជួរដេកមួយ។
តើស៊េរីពេលវេលាអាចប្រើនៅឯណា? មានអ្នកណាមានគំនិតទេ?
- នៅក្នុង DevOps អ្នកអាចវាស់ CPU, RAM, network, rps, ចំនួននៃកំហុស។ល។
- IoT - យើងអាចវាស់សីតុណ្ហភាព សម្ពាធ កូអរដោនេភូមិសាស្ត្រ និងអ្វីផ្សេងទៀត។
- ហិរញ្ញវត្ថុផងដែរ - យើងអាចតាមដានតម្លៃសម្រាប់ភាគហ៊ុន និងរូបិយប័ណ្ណគ្រប់ប្រភេទ។
- លើសពីនេះទៀត ស៊េរីពេលវេលាអាចត្រូវបានប្រើក្នុងការត្រួតពិនិត្យដំណើរការផលិតកម្មនៅក្នុងរោងចក្រ។ យើងមានអ្នកប្រើប្រាស់ដែលប្រើ VictoriaMetrics ដើម្បីត្រួតពិនិត្យទួរប៊ីនខ្យល់ សម្រាប់មនុស្សយន្ត។
- ស៊េរីពេលវេលាក៏មានប្រយោជន៍សម្រាប់ការប្រមូលព័ត៌មានពីឧបករណ៍ចាប់សញ្ញានៃឧបករណ៍ផ្សេងៗ។ ឧទាហរណ៍សម្រាប់ម៉ាស៊ីន; សម្រាប់វាស់សម្ពាធកង់រថយន្ត; សម្រាប់វាស់ល្បឿន, ចម្ងាយ; សម្រាប់វាស់ការប្រើប្រាស់សាំង។ល។
- ស៊េរីពេលវេលាក៏អាចត្រូវបានប្រើដើម្បីត្រួតពិនិត្យយន្តហោះផងដែរ។ យន្តហោះនីមួយៗមានប្រអប់ខ្មៅដែលប្រមូលនូវស៊េរីពេលវេលាសម្រាប់ប៉ារ៉ាម៉ែត្រផ្សេងៗនៃសុខភាពរបស់យន្តហោះ។ ស៊េរីពេលវេលាក៏ត្រូវបានគេប្រើនៅក្នុងឧស្សាហកម្មអវកាសផងដែរ។
- ការថែទាំសុខភាពគឺ សម្ពាធឈាម ជីពចរ។ល។
ប្រហែលជាមានកម្មវិធីជាច្រើនទៀតដែលខ្ញុំភ្លេច ប៉ុន្តែខ្ញុំសង្ឃឹមថាអ្នកយល់ថាស៊េរីពេលវេលាត្រូវបានប្រើប្រាស់យ៉ាងសកម្មនៅក្នុងពិភពសម័យទំនើប។ ហើយបរិមាណនៃការប្រើប្រាស់របស់ពួកគេកំពុងកើនឡើងជារៀងរាល់ឆ្នាំ។
ហេតុអ្វីបានជាអ្នកត្រូវការមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលា? ហេតុអ្វីបានជាអ្នកមិនអាចប្រើមូលដ្ឋានទិន្នន័យទំនាក់ទំនងធម្មតាដើម្បីរក្សាទុកស៊េរីពេលវេលា?
ដោយសារតែស៊េរីពេលវេលាជាធម្មតាផ្ទុកនូវព័ត៌មានមួយចំនួនធំ ដែលពិបាករក្សាទុក និងដំណើរការក្នុងមូលដ្ឋានទិន្នន័យធម្មតា។ ដូច្នេះ មូលដ្ឋានទិន្នន័យឯកទេសសម្រាប់ស៊េរីពេលវេលាបានបង្ហាញខ្លួន។ មូលដ្ឋានទាំងនេះមានប្រសិទ្ធភាពរក្សាទុកពិន្ទុ (timestamp, value)
ជាមួយនឹងសោដែលបានផ្តល់ឱ្យ។ ពួកគេផ្តល់ API សម្រាប់ការអានទិន្នន័យដែលបានរក្សាទុកដោយកូនសោ ដោយគូតម្លៃសោតែមួយ ឬដោយគូតម្លៃសោច្រើន ឬដោយ regexp ។ ឧទាហរណ៍ អ្នកចង់ស្វែងរកការផ្ទុកស៊ីភីយូនៃសេវាកម្មរបស់អ្នកទាំងអស់នៅក្នុងមជ្ឈមណ្ឌលទិន្នន័យនៅអាមេរិក បន្ទាប់មកអ្នកត្រូវប្រើសំណួរក្លែងក្លាយនេះ។
ជាធម្មតា មូលដ្ឋានទិន្នន័យស៊េរីពេលវេលាផ្តល់ភាសាសំណួរពិសេស ពីព្រោះស៊េរីពេលវេលា SQL មិនសមល្អទេ។ ទោះបីជាមានមូលដ្ឋានទិន្នន័យដែលគាំទ្រ SQL ក៏ដោយក៏វាមិនសមរម្យខ្លាំងដែរ។ ភាសាសំណួរដូចជា
នេះគឺជាអ្វីដែលស្ថាបត្យកម្មមូលដ្ឋានទិន្នន័យស៊េរីសម័យទំនើបមើលទៅដូចជាការប្រើ VictoriaMetrics ជាឧទាហរណ៍។
វាមានពីរផ្នែក។ នេះគឺជាការផ្ទុកសម្រាប់សន្ទស្សន៍ដាក់បញ្ច្រាស និងការផ្ទុកសម្រាប់តម្លៃស៊េរីពេលវេលា។ ឃ្លាំងទាំងនេះត្រូវបានបំបែក។
នៅពេលកំណត់ត្រាថ្មីមកដល់ក្នុងមូលដ្ឋានទិន្នន័យ យើងចូលប្រើលិបិក្រមដាក់បញ្ច្រាសជាដំបូងដើម្បីស្វែងរកលេខសម្គាល់ស៊េរីពេលវេលាសម្រាប់សំណុំដែលបានផ្តល់ឱ្យ។ label=value
សម្រាប់ម៉ែត្រដែលបានផ្តល់ឱ្យ។ យើងរកឃើញអត្តសញ្ញាណនេះ ហើយរក្សាទុកតម្លៃនៅក្នុងឃ្លាំងទិន្នន័យ។
នៅពេលដែលសំណើមួយមកដើម្បីទាញយកទិន្នន័យពី TSDB ដំបូងយើងទៅកាន់សន្ទស្សន៍ដាក់បញ្ច្រាស។ ចូរយើងទទួលបានអ្វីគ្រប់យ៉ាង timeseries_ids
កំណត់ត្រាដែលត្រូវនឹងសំណុំនេះ។ label=value
. ហើយបន្ទាប់មកយើងទទួលបានទិន្នន័យចាំបាច់ទាំងអស់ពីឃ្លាំងទិន្នន័យដែលធ្វើលិបិក្រមដោយ timeseries_ids
.
សូមក្រឡេកមើលឧទាហរណ៍អំពីរបៀបដែលមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលាដំណើរការសំណួរជ្រើសរើសចូល។
- ដំបូងនាងទទួលបានអ្វីៗទាំងអស់។
timeseries_ids
ពីសន្ទស្សន៍ដាក់បញ្ច្រាសដែលមានគូដែលបានផ្តល់ឱ្យlabel=value
ឬបំពេញកន្សោមធម្មតាដែលបានផ្តល់ឱ្យ។ - បន្ទាប់មកវាទៅយកចំណុចទិន្នន័យទាំងអស់ពីការផ្ទុកទិន្នន័យនៅចន្លោះពេលដែលបានផ្តល់ឱ្យសម្រាប់អ្នកដែលបានរកឃើញ
timeseries_ids
. - បន្ទាប់ពីនេះ មូលដ្ឋានទិន្នន័យធ្វើការគណនាមួយចំនួនលើចំណុចទិន្នន័យទាំងនេះ តាមការស្នើសុំរបស់អ្នកប្រើប្រាស់។ ហើយបន្ទាប់មកវាត្រឡប់ចម្លើយ។
នៅក្នុងបទបង្ហាញនេះ ខ្ញុំនឹងប្រាប់អ្នកអំពីផ្នែកទីមួយ។ នេះគឺជាការស្វែងរក timeseries_ids
ដោយសន្ទស្សន៍បញ្ច្រាស។ អ្នកអាចមើលអំពីផ្នែកទីពីរ និងផ្នែកទីបីនៅពេលក្រោយ
ចូរបន្តទៅសន្ទស្សន៍ដាក់បញ្ច្រាស។ មនុស្សជាច្រើនប្រហែលជាគិតថានេះគឺសាមញ្ញ។ តើអ្នកណាដឹងថាតើសន្ទស្សន៍បញ្ច្រាសគឺជាអ្វី និងរបៀបដែលវាដំណើរការ? អូ មនុស្សមិនច្រើនទៀតទេ។ ចូរយើងព្យាយាមយល់ពីអ្វីដែលវាគឺជា។
តាមពិតវាសាមញ្ញណាស់។ វាគ្រាន់តែជាវចនានុក្រមដែលគូសផែនទីគន្លឹះទៅនឹងតម្លៃ។ តើអ្វីជាគន្លឹះ? ប្តីប្រពន្ធនេះ។ label=value
ដែលជាកន្លែង label
и value
- ទាំងនេះគឺជាបន្ទាត់។ ហើយតម្លៃគឺជាសំណុំ timeseries_ids
ដែលរួមបញ្ចូលគូដែលបានផ្តល់ឱ្យ label=value
.
លិបិក្រមដាក់បញ្ច្រាសអនុញ្ញាតឱ្យអ្នកស្វែងរកអ្វីគ្រប់យ៉ាងយ៉ាងឆាប់រហ័ស timeseries_ids
ដែលបានផ្តល់ឱ្យ label=value
.
វាក៏អនុញ្ញាតឱ្យអ្នកស្វែងរកយ៉ាងឆាប់រហ័សផងដែរ។ timeseries_ids
ស៊េរីពេលវេលាសម្រាប់គូជាច្រើន។ label=value
ឬសម្រាប់គូស្នេហ៍ label=regexp
. តើរឿងនេះកើតឡើងដោយរបៀបណា? ដោយស្វែងរកចំនុចប្រសព្វនៃសំណុំ timeseries_ids
សម្រាប់គូនីមួយៗ label=value
.
សូមក្រឡេកមើលការអនុវត្តផ្សេងៗនៃសន្ទស្សន៍ដាក់បញ្ច្រាស។ ចូរចាប់ផ្តើមជាមួយនឹងការអនុវត្តដ៏សាមញ្ញបំផុត។ នាងមើលទៅដូចនេះ។
មុខងារ getMetricIDs
ទទួលបានបញ្ជីខ្សែ។ បន្ទាត់នីមួយៗមាន label=value
. មុខងារនេះត្រឡប់បញ្ជី metricIDs
.
តើវាដំណើរការយ៉ាងដូចម្តេច? នៅទីនេះយើងមានអថេរសកលហៅថា invertedIndex
. នេះជាវចនានុក្រមធម្មតា (map
) ដែលនឹងកំណត់ខ្សែអក្សរដើម្បីកាត់ ints ។ បន្ទាត់មាន label=value
.
ការអនុវត្តមុខងារ៖ ទទួលបាន metricIDs
សម្រាប់ដំបូង label=value
បន្ទាប់មកយើងឆ្លងកាត់អ្វីៗផ្សេងទៀត។ label=value
, យើងទទួលបានវា។ metricIDs
សម្រាប់ពួកគេ។ ហើយហៅមុខងារ intersectInts
ដែលនឹងត្រូវបានពិភាក្សាដូចខាងក្រោម។ ហើយមុខងារនេះត្រឡប់ចំនុចប្រសព្វនៃបញ្ជីទាំងនេះ។
ដូចដែលអ្នកអាចឃើញការអនុវត្តសន្ទស្សន៍បញ្ច្រាសមិនស្មុគស្មាញទេ។ ប៉ុន្តែនេះជាការអនុវត្តបែបឆោតល្ងង់។ តើវាមានគុណវិបត្តិអ្វីខ្លះ? គុណវិបត្តិចម្បងនៃការអនុវត្តឆោតល្ងង់គឺថាសន្ទស្សន៍បញ្ច្រាសបែបនេះត្រូវបានរក្សាទុកក្នុង RAM ។ បន្ទាប់ពីចាប់ផ្តើមកម្មវិធីឡើងវិញ យើងបាត់បង់លិបិក្រមនេះ។ មិនមានការរក្សាទុកសន្ទស្សន៍នេះទៅក្នុងថាសទេ។ លិបិក្រមដាក់បញ្ច្រាសបែបនេះទំនងជាមិនសមរម្យសម្រាប់មូលដ្ឋានទិន្នន័យទេ។
គុណវិបត្តិទីពីរក៏ទាក់ទងនឹងការចងចាំផងដែរ។ លិបិក្រមដាក់បញ្ច្រាសត្រូវតែសមនឹង RAM ។ ប្រសិនបើវាលើសពីទំហំ RAM នោះច្បាស់ណាស់យើងនឹងទទួលបាន - កំហុសនៃអង្គចងចាំ។ ហើយកម្មវិធីនឹងមិនដំណើរការទេ។
បញ្ហានេះអាចត្រូវបានដោះស្រាយដោយប្រើដំណោះស្រាយដែលត្រៀមរួចជាស្រេចដូចជា
សរុបមក យើងត្រូវការ Database ដែលអនុញ្ញាតឱ្យយើងធ្វើប្រតិបត្តិការបីយ៉ាងរហ័ស។
- ប្រតិបត្តិការដំបូងគឺការថត
ключ-значение
ទៅកាន់មូលដ្ឋានទិន្នន័យនេះ។ នាងធ្វើយ៉ាងនេះយ៉ាងលឿនទៅណាключ-значение
គឺជាខ្សែអាត់បំពាន។ - ប្រតិបត្តិការទីពីរគឺការស្វែងរករហ័សសម្រាប់តម្លៃដោយប្រើសោដែលបានផ្តល់ឱ្យ។
- ហើយប្រតិបត្តិការទីបីគឺជាការស្វែងរករហ័សសម្រាប់តម្លៃទាំងអស់ដោយបុព្វបទដែលបានផ្តល់ឱ្យ។
LevelDB និង RocksDB - មូលដ្ឋានទិន្នន័យទាំងនេះត្រូវបានបង្កើតឡើងដោយ Google និង Facebook ។ ដំបូងបង្អស់ LevelDB ។ បន្ទាប់មក បុរសមកពី Facebook បានយក LevelDB ហើយចាប់ផ្តើមកែលម្អវា ពួកគេបានបង្កើត RocksDB ។ ឥឡូវនេះ មូលដ្ឋានទិន្នន័យខាងក្នុងស្ទើរតែទាំងអស់ដំណើរការនៅលើ RocksDB នៅក្នុង Facebook រួមទាំងទិន្នន័យដែលត្រូវបានផ្ទេរទៅ RocksDB និង MySQL ។ ពួកគេបានដាក់ឈ្មោះគាត់
សន្ទស្សន៍ដាក់បញ្ច្រាសអាចត្រូវបានអនុវត្តដោយប្រើ LevelDB ។ តើត្រូវធ្វើដូចម្តេច? យើងរក្សាទុកជាសោ label=value
. ហើយតម្លៃគឺជាការកំណត់អត្តសញ្ញាណនៃស៊េរីពេលវេលាដែលគូមានវត្តមាន label=value
.
ប្រសិនបើយើងមានស៊េរីពេលវេលាជាច្រើនជាមួយនឹងគូដែលបានផ្តល់ឱ្យ label=value
បន្ទាប់មកវានឹងមានជួរជាច្រើននៅក្នុងមូលដ្ឋានទិន្នន័យនេះដែលមានសោដូចគ្នា និងខុសគ្នា timeseries_ids
. ដើម្បីទទួលបានបញ្ជីទាំងអស់។ timeseries_ids
ដែលចាប់ផ្តើមជាមួយនេះ។ label=prefix
យើងធ្វើការស្កេនជួរដែលមូលដ្ឋានទិន្នន័យនេះត្រូវបានធ្វើឱ្យប្រសើរ។ នោះគឺយើងជ្រើសរើសបន្ទាត់ទាំងអស់ដែលចាប់ផ្តើមជាមួយ label=prefix
និងទទួលបានចាំបាច់ timeseries_ids
.
នេះជាការអនុវត្តគំរូនៃអ្វីដែលវានឹងមើលទៅដូចនៅក្នុង Go ។ យើងមានសន្ទស្សន៍បញ្ច្រាស។ នេះគឺជា LevelDB ។
មុខងារគឺដូចគ្នាទៅនឹងការអនុវត្តឆោតល្ងង់។ វាធ្វើឡើងវិញនូវការអនុវត្តបែបឆោតល្ងង់ស្ទើរតែមួយជួរ។ ចំណុចតែមួយគត់គឺថាជំនួសឱ្យការងាកទៅ map
យើងចូលប្រើសន្ទស្សន៍បញ្ច្រាស។ យើងទទួលបានតម្លៃទាំងអស់សម្រាប់ដំបូង label=value
. បន្ទាប់មកយើងឆ្លងកាត់គូដែលនៅសល់ទាំងអស់។ label=value
និងទទួលបានសំណុំ metricIDs ដែលត្រូវគ្នាសម្រាប់ពួកគេ។ បន្ទាប់មកយើងរកឃើញផ្លូវបំបែក។
អ្វីគ្រប់យ៉ាងហាក់ដូចជាល្អ ប៉ុន្តែមានគុណវិបត្តិចំពោះដំណោះស្រាយនេះ។ VictoriaMetrics ដំបូងបានអនុវត្តសន្ទស្សន៍ដាក់បញ្ច្រាសដោយផ្អែកលើ LevelDB ។ ប៉ុន្តែនៅទីបំផុត ខ្ញុំត្រូវតែបោះបង់វាចោល។
ហេតុអ្វី? ដោយសារតែ LevelDB គឺយឺតជាងការអនុវត្តដោយឆោតល្ងង់។ នៅក្នុងការអនុវត្តដោយឆោតល្ងង់ ដែលបានផ្ដល់ឱ្យនូវកូនសោរមួយ យើងទាញយកចំណែកទាំងមូលភ្លាមៗ metricIDs
. នេះគឺជាប្រតិបត្តិការលឿនណាស់ - ចំណិតទាំងមូលរួចរាល់សម្រាប់ការប្រើប្រាស់។
នៅក្នុង LevelDB រាល់ពេលដែលមុខងារត្រូវបានហៅ GetValues
អ្នកត្រូវឆ្លងកាត់បន្ទាត់ទាំងអស់ដែលចាប់ផ្តើមជាមួយ label=value
. និងទទួលបានតម្លៃសម្រាប់បន្ទាត់នីមួយៗ timeseries_ids
. បែបនេះ timeseries_ids
ប្រមូលបំណែកទាំងនេះ timeseries_ids
. ជាក់ស្តែង នេះគឺយឺតជាងការចូលប្រើផែនទីធម្មតាដោយគន្លឹះ។
គុណវិបត្តិទីពីរគឺថា LevelDB ត្រូវបានសរសេរនៅក្នុង C. ការហៅមុខងារ C ពី Go គឺមិនលឿនទេ។ វាត្រូវការពេលរាប់រយណាណូវិនាទី។ នេះមិនលឿនទេ ព្រោះបើប្រៀបធៀបទៅនឹងការហៅមុខងារធម្មតាដែលសរសេរក្នុងដំណើរការដែលចំណាយពេល 1-5 nanoseconds ភាពខុសគ្នាក្នុងការអនុវត្តគឺរាប់សិបដង។ សម្រាប់ VictoriaMetrics នេះគឺជាកំហុសធ្ងន់ធ្ងរ :)
ដូច្នេះ ខ្ញុំបានសរសេរការអនុវត្តផ្ទាល់របស់ខ្ញុំអំពីសន្ទស្សន៍ដាក់បញ្ច្រាស។ ហើយគាត់បានហៅនាង
Mergeset ផ្អែកលើរចនាសម្ព័ន្ធទិន្នន័យ MergeTree ។ រចនាសម្ព័ន្ធទិន្នន័យនេះត្រូវបានខ្ចីពី ClickHouse ។ ជាក់ស្តែង ការរួមបញ្ចូលគ្នាគួរតែត្រូវបានធ្វើឱ្យប្រសើរសម្រាប់ការស្វែងរករហ័ស timeseries_ids
នេះបើយោងតាមគន្លឹះដែលបានផ្តល់ឱ្យ។ Mergeset ត្រូវបានសរសេរទាំងស្រុងនៅក្នុង Go ។ អ្នកអាចមើលឃើញ
API រួមបញ្ចូលគ្នាគឺស្រដៀងទៅនឹង LevelDB និង RocksDB ។ នោះគឺវាអនុញ្ញាតឱ្យអ្នករក្សាទុកកំណត់ត្រាថ្មីនៅទីនោះបានយ៉ាងឆាប់រហ័ស ហើយជ្រើសរើសកំណត់ត្រាយ៉ាងរហ័សតាមបុព្វបទដែលបានផ្តល់ឱ្យ។
យើងនឹងនិយាយអំពីគុណវិបត្តិនៃការរួមបញ្ចូលគ្នានៅពេលក្រោយ។ ឥឡូវនេះសូមនិយាយអំពីបញ្ហាអ្វីដែលកើតឡើងជាមួយ VictoriaMetrics ក្នុងផលិតកម្ម នៅពេលអនុវត្តសន្ទស្សន៍បញ្ច្រាស។
ហេតុអ្វីបានជាពួកគេកើតឡើង?
មូលហេតុទី 1 គឺអត្រាញញួរខ្ពស់។ បកប្រែទៅជាភាសារុស្សី នេះគឺជាការផ្លាស់ប្តូរជាញឹកញាប់នៅក្នុងស៊េរីពេលវេលា។ នេះគឺជាពេលដែលស៊េរីពេលវេលាបញ្ចប់ ហើយស៊េរីថ្មីចាប់ផ្តើម ឬស៊េរីពេលវេលាថ្មីជាច្រើនចាប់ផ្តើម។ ហើយរឿងនេះកើតឡើងជាញឹកញាប់។
មូលហេតុទីពីរគឺចំនួនដ៏ច្រើននៃស៊េរីពេលវេលា។ នៅដើមដំបូងនៅពេលដែលការត្រួតពិនិត្យកំពុងទទួលបានប្រជាប្រិយភាពចំនួននៃស៊េរីពេលវេលាគឺតូច។ ឧទាហរណ៍ សម្រាប់កុំព្យូទ័រនីមួយៗ អ្នកត្រូវត្រួតពិនិត្យស៊ីភីយូ អង្គចងចាំ បណ្តាញ និងការផ្ទុកថាស។ 4 ស៊េរីពេលវេលាក្នុងមួយកុំព្យូទ័រ។ ឧបមាថាអ្នកមានកុំព្យូទ័រចំនួន 100 និងស៊េរីពេលវេលាចំនួន 400 ។ នេះគឺតិចតួចណាស់។
យូរៗទៅ មនុស្សបានយល់ឃើញថា ពួកគេអាចវាស់វែងព័ត៌មានលម្អិតបន្ថែមទៀត។ ជាឧទាហរណ៍ វាស់បន្ទុកមិនមែនរបស់ processor ទាំងមូលទេ ប៉ុន្តែដាច់ដោយឡែកពីស្នូល processor នីមួយៗ។ ប្រសិនបើអ្នកមាន 40 processor cores នោះអ្នកមានស៊េរីពេលវេលា 40 ដងទៀតដើម្បីវាស់បន្ទុក processor ។
ប៉ុន្តែនោះមិនមែនទាំងអស់នោះទេ។ ស្នូលដំណើរការនីមួយៗអាចមានស្ថានភាពជាច្រើនដូចជា ទំនេរ នៅពេលដែលវានៅទំនេរ។ ហើយក៏ធ្វើការក្នុងទំហំអ្នកប្រើដែរ ធ្វើការក្នុងចន្លោះខឺណែល និងរដ្ឋផ្សេងទៀត។ ហើយរដ្ឋនីមួយៗក៏អាចត្រូវបានវាស់វែងជាស៊េរីពេលវេលាដាច់ដោយឡែកផងដែរ។ នេះលើសពីនេះទៀតបង្កើនចំនួនជួរដេក 7-8 ដង។
ពីម៉ែត្រមួយ យើងទទួលបាន 40 x 8 = 320 ម៉ែត្រសម្រាប់តែកុំព្យូទ័រមួយប៉ុណ្ណោះ។ គុណនឹង 100 យើងទទួលបាន 32 ជំនួសឱ្យ 000 ។
បន្ទាប់មក Kubernetes បានមកជាមួយ។ ហើយវាកាន់តែអាក្រក់ទៅៗ ដោយសារតែ Kubernetes អាចរៀបចំសេវាកម្មផ្សេងៗជាច្រើន។ សេវាកម្មនីមួយៗនៅក្នុង Kubernetes មានផតថលជាច្រើន។ ហើយទាំងអស់នេះចាំបាច់ត្រូវត្រួតពិនិត្យ។ លើសពីនេះទៀត យើងមានការដាក់ឱ្យប្រើប្រាស់ជាប្រចាំនូវកំណែថ្មីនៃសេវាកម្មរបស់អ្នក។ សម្រាប់កំណែថ្មីនីមួយៗ ស៊េរីពេលវេលាថ្មីត្រូវតែត្រូវបានបង្កើត។ ជាលទ្ធផល ចំនួននៃស៊េរីពេលវេលាកើនឡើងជានិទស្សន្ត ហើយយើងកំពុងប្រឈមមុខនឹងបញ្ហានៃស៊េរីពេលវេលាដ៏ច្រើន ដែលត្រូវបានគេហៅថា high-cardinality ។ VictoriaMetrics ដោះស្រាយវាដោយជោគជ័យ បើប្រៀបធៀបទៅនឹងមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលាផ្សេងទៀត។
សូមក្រឡេកមើលឱ្យកាន់តែដិតដល់អំពីអត្រានៃការកូរខ្ពស់។ តើអ្វីបណ្តាលឱ្យមានអត្រាកើនឡើងខ្ពស់ក្នុងផលិតកម្ម? ដោយសារតែអត្ថន័យមួយចំនួននៃស្លាក និងស្លាកកំពុងផ្លាស់ប្តូរឥតឈប់ឈរ។
ឧទាហរណ៍ យក Kubernetes ដែលមានគោលគំនិត deployment
ពោលគឺនៅពេលដែលកំណែថ្មីនៃកម្មវិធីរបស់អ្នកត្រូវបានបញ្ចេញ។ សម្រាប់ហេតុផលមួយចំនួន អ្នកអភិវឌ្ឍន៍ Kubernetes បានសម្រេចចិត្តបន្ថែមលេខសម្គាល់ការដាក់ឱ្យប្រើប្រាស់ទៅស្លាក។
តើនេះនាំទៅរកអ្វី? លើសពីនេះទៅទៀត ជាមួយនឹងការដាក់ពង្រាយថ្មីនីមួយៗ ស៊េរីពេលវេលាចាស់ទាំងអស់ត្រូវបានរំខាន ហើយជំនួសឱ្យពួកវា ស៊េរីពេលវេលាថ្មីចាប់ផ្តើមជាមួយនឹងតម្លៃស្លាកថ្មី deployment_id
. អាចមានរាប់រយរាប់ពាន់នាក់ និងរាប់លានជួរ។
ចំណុចសំខាន់នៃរឿងទាំងអស់នេះគឺថាចំនួនសរុបនៃស៊េរីពេលវេលាកើនឡើង ប៉ុន្តែចំនួននៃស៊េរីពេលវេលាដែលបច្ចុប្បន្នសកម្ម និងទទួលទិន្នន័យនៅតែថេរ។ រដ្ឋនេះត្រូវបានគេហៅថាអត្រាញាក់ខ្ពស់។
បញ្ហាចម្បងនៃអត្រាកូរខ្ពស់គឺដើម្បីធានាបាននូវល្បឿនស្វែងរកថេរសម្រាប់ស៊េរីពេលវេលាទាំងអស់សម្រាប់សំណុំស្លាកដែលបានផ្តល់ឱ្យក្នុងរយៈពេលជាក់លាក់ណាមួយ។ ជាធម្មតា នេះគឺជាចន្លោះពេលសម្រាប់ម៉ោងចុងក្រោយ ឬថ្ងៃចុងក្រោយ។
តើធ្វើដូចម្តេចដើម្បីដោះស្រាយបញ្ហានេះ? នេះជាជម្រើសដំបូង។ នេះគឺដើម្បីបែងចែកសន្ទស្សន៍ដាក់បញ្ច្រាសទៅជាផ្នែកឯករាជ្យតាមពេលវេលា។ នោះគឺ ចន្លោះពេលខ្លះឆ្លងកាត់ យើងបញ្ចប់ការធ្វើការជាមួយសន្ទស្សន៍បញ្ច្រាសបច្ចុប្បន្ន។ ហើយបង្កើតលិបិក្រមដាក់បញ្ច្រាសថ្មី។ ចន្លោះពេលមួយទៀតឆ្លងកាត់ យើងបង្កើតមួយទៀត និងមួយទៀត។
ហើយនៅពេលយកគំរូពីសន្ទស្សន៍ដាក់បញ្ច្រាសទាំងនេះ យើងរកឃើញសំណុំនៃសន្ទស្សន៍បញ្ច្រាសដែលធ្លាក់ក្នុងចន្លោះដែលបានផ្តល់ឱ្យ។ ហើយតាមនោះ យើងជ្រើសរើសលេខសម្គាល់នៃស៊េរីពេលវេលាពីទីនោះ។
វាជួយសន្សំសំចៃធនធាន ពីព្រោះយើងមិនចាំបាច់មើលផ្នែកដែលមិនធ្លាក់ក្នុងចន្លោះពេលដែលបានផ្តល់ឱ្យនោះទេ។ នោះជាធម្មតា ប្រសិនបើយើងជ្រើសរើសទិន្នន័យសម្រាប់ម៉ោងចុងក្រោយ នោះសម្រាប់ចន្លោះពេលមុន យើងរំលងសំណើ។
មានជម្រើសមួយផ្សេងទៀតដើម្បីដោះស្រាយបញ្ហានេះ។ នេះគឺដើម្បីរក្សាទុកសម្រាប់ថ្ងៃនីមួយៗនូវបញ្ជីលេខសម្គាល់ដាច់ដោយឡែកនៃស៊េរីពេលវេលាដែលបានកើតឡើងនៅថ្ងៃនោះ។
អត្ថប្រយោជន៍នៃដំណោះស្រាយនេះជាងដំណោះស្រាយមុនគឺថាយើងមិនចម្លងព័ត៌មានស៊េរីពេលវេលាដែលមិនបាត់តាមពេលវេលា។ ពួកគេមានវត្តមានឥតឈប់ឈរហើយមិនផ្លាស់ប្តូរ។
គុណវិបត្តិគឺថាដំណោះស្រាយបែបនេះកាន់តែពិបាកអនុវត្ត និងពិបាកក្នុងការបំបាត់កំហុស។ ហើយ VictoriaMetrics បានជ្រើសរើសដំណោះស្រាយនេះ។ នេះជារបៀបដែលវាបានកើតឡើងជាប្រវត្តិសាស្ត្រ។ ដំណោះស្រាយនេះក៏ដំណើរការបានល្អផងដែរបើធៀបនឹងវិធីមុន។ ដោយសារតែដំណោះស្រាយនេះមិនត្រូវបានអនុវត្តដោយសារតែការពិតដែលថាវាចាំបាច់ក្នុងការស្ទួនទិន្នន័យនៅក្នុងភាគថាសនីមួយៗសម្រាប់ស៊េរីពេលវេលាដែលមិនផ្លាស់ប្តូរពោលគឺមិនបាត់តាមពេលវេលា។ VictoriaMetrics ត្រូវបានធ្វើឱ្យប្រសើរឡើងជាចម្បងសម្រាប់ការប្រើប្រាស់ទំហំថាស ហើយការអនុវត្តពីមុនបានធ្វើឱ្យការប្រើប្រាស់ទំហំថាសកាន់តែអាក្រក់។ ប៉ុន្តែការអនុវត្តនេះគឺសមស្របជាងសម្រាប់ការកាត់បន្ថយការប្រើប្រាស់ទំហំថាស ដូច្នេះវាត្រូវបានជ្រើសរើស។
ខ្ញុំត្រូវប្រយុទ្ធជាមួយនាង។ ការតស៊ូគឺថានៅក្នុងការអនុវត្តនេះអ្នកនៅតែត្រូវជ្រើសរើសចំនួនធំជាងនេះ។ timeseries_ids
សម្រាប់ទិន្នន័យជាងពេលដែលសន្ទស្សន៍ដាក់បញ្ច្រាសត្រូវបានបែងចែកពេលវេលា។
តើយើងបានដោះស្រាយបញ្ហានេះដោយរបៀបណា? យើងបានដោះស្រាយវាតាមរបៀបដើម - ដោយរក្សាទុកឧបករណ៍កំណត់ស៊េរីពេលវេលាជាច្រើននៅក្នុងធាតុលិបិក្រមដាក់បញ្ច្រាសនីមួយៗ ជំនួសឱ្យឧបករណ៍កំណត់អត្តសញ្ញាណមួយ។ នោះគឺយើងមានគន្លឹះមួយ។ label=value
ដែលកើតឡើងនៅគ្រប់ស៊េរីពេលវេលា។ ហើយឥឡូវនេះយើងសន្សំបានច្រើន។ timeseries_ids
នៅក្នុងការចូលមួយ។
នេះជាឧទាហរណ៍មួយ។ ពីមុនយើងមានធាតុ N ប៉ុន្តែឥឡូវនេះយើងមានធាតុមួយដែលបុព្វបទគឺដូចគ្នានឹងធាតុផ្សេងទៀតទាំងអស់។ សម្រាប់ធាតុមុន តម្លៃមានលេខសម្គាល់ស៊េរីពេលវេលាទាំងអស់។
នេះធ្វើឱ្យវាអាចបង្កើនល្បឿនស្កេននៃសន្ទស្សន៍បញ្ច្រាសបែបនេះរហូតដល់ 10 ដង។ ហើយវាអនុញ្ញាតឱ្យយើងកាត់បន្ថយការប្រើប្រាស់អង្គចងចាំសម្រាប់ឃ្លាំងសម្ងាត់ ព្រោះឥឡូវនេះយើងរក្សាទុកខ្សែអក្សរ label=value
ម្តងក្នុងឃ្លាំងសម្ងាត់រួមគ្នា N ដង។ ហើយបន្ទាត់នេះអាចមានទំហំធំ ប្រសិនបើអ្នកទុកបន្ទាត់វែងៗនៅក្នុងស្លាក និងស្លាករបស់អ្នក ដែល Kubernetes ចូលចិត្តរុញនៅទីនោះ។
ជម្រើសមួយទៀតសម្រាប់បង្កើនល្បឿនការស្វែងរកនៅលើលិបិក្រមបញ្ច្រាសគឺ sharding ។ ការបង្កើតលិបិក្រមដាក់បញ្ច្រាសជាច្រើនជំនួសឱ្យមួយ និងការចែករំលែកទិន្នន័យរវាងពួកវាដោយគន្លឹះ។ នេះគឺជាសំណុំ key=value
ចំហាយ។ នោះគឺយើងទទួលបានលិបិក្រមបញ្ច្រាសឯករាជ្យជាច្រើន ដែលយើងអាចសួរស្របគ្នាលើ processors ជាច្រើន។ ការអនុវត្តពីមុនបានអនុញ្ញាតឱ្យដំណើរការតែក្នុងរបៀបដំណើរការតែមួយប៉ុណ្ណោះ ពោលគឺការស្កែនទិន្នន័យតែមួយស្នូល។ ដំណោះស្រាយនេះអនុញ្ញាតឱ្យអ្នកស្កេនទិន្នន័យនៅលើស្នូលជាច្រើនក្នុងពេលតែមួយ ដូចដែល ClickHouse ចូលចិត្តធ្វើ។ នេះជាអ្វីដែលយើងគ្រោងនឹងអនុវត្ត។
ឥឡូវនេះសូមត្រលប់ទៅចៀមរបស់យើងវិញ - ទៅមុខងារប្រសព្វ timeseries_ids
. ចូរយើងពិចារណាថាតើការអនុវត្តអាចមានអ្វីខ្លះ។ មុខងារនេះអនុញ្ញាតឱ្យអ្នកស្វែងរក timeseries_ids
សម្រាប់សំណុំដែលបានផ្តល់ឱ្យ label=value
.
ជម្រើសទីមួយគឺការអនុវត្តដោយឆោតល្ងង់។ រង្វិលជុំពីរ។ នៅទីនេះយើងទទួលបានមុខងារបញ្ចូល intersectInts
ពីរចំណិត - a
и b
. នៅទិន្នផល វាគួរតែត្រលប់មកយើងវិញនូវចំនុចប្រសព្វនៃចំណិតទាំងនេះ។
ការអនុវត្តឆោតល្ងង់មើលទៅដូចនេះ។ យើងធ្វើម្តងទៀតលើតម្លៃទាំងអស់ពីចំណិត a
, នៅខាងក្នុងរង្វិលជុំនេះយើងឆ្លងកាត់តម្លៃទាំងអស់នៃចំណិត b
. ហើយយើងប្រៀបធៀបពួកគេ។ ប្រសិនបើពួកគេត្រូវគ្នា នោះយើងបានរកឃើញចំនុចប្រសព្វមួយ។ ហើយរក្សាទុកវានៅក្នុង result
.
តើមានគុណវិបត្តិអ្វីខ្លះ? ភាពស្មុគស្មាញ quadratic គឺជាគុណវិបត្តិចម្បងរបស់វា។ ឧទាហរណ៍ប្រសិនបើវិមាត្ររបស់អ្នកត្រូវបានកាត់ a
и b
មួយលានក្នុងពេលតែមួយ បន្ទាប់មកមុខងារនេះនឹងមិនផ្តល់ចម្លើយដល់អ្នកទេ។ ដោយសារតែវានឹងត្រូវការធ្វើឡើងវិញមួយពាន់ពាន់លាន ដែលជាចំនួនច្រើន សូម្បីតែកុំព្យូទ័រទំនើបក៏ដោយ។
ការអនុវត្តទីពីរគឺផ្អែកលើផែនទី។ យើងបង្កើតផែនទី។ យើងដាក់តម្លៃទាំងអស់ពី slice ទៅក្នុងផែនទីនេះ។ a
. បន្ទាប់មកយើងឆ្លងកាត់ចំណិតនៅក្នុងរង្វិលជុំដាច់ដោយឡែកមួយ។ b
. ហើយយើងពិនិត្យមើលថាតើតម្លៃនេះគឺមកពីចំណិត b
នៅក្នុងផែនទី។ ប្រសិនបើវាមានវត្តមានបន្ទាប់មកបន្ថែមវាទៅលទ្ធផល។
តើមានអត្ថប្រយោជន៍អ្វីខ្លះ? អត្ថប្រយោជន៍គឺថាមានតែភាពស្មុគស្មាញលីនេអ៊ែរប៉ុណ្ណោះ។ នោះគឺមុខងារនឹងប្រតិបត្តិលឿនជាងមុនសម្រាប់ចំណិតធំៗ។ សម្រាប់ផ្នែកមួយលានទំហំ មុខងារនេះនឹងដំណើរការក្នុង 2 លានដង ដែលផ្ទុយពីការធ្វើឡើងវិញចំនួនពាន់ពាន់លាននៃមុខងារមុន។
គុណវិបត្តិគឺថាមុខងារនេះត្រូវការអង្គចងចាំបន្ថែមទៀតដើម្បីបង្កើតផែនទីនេះ។
គុណវិបត្តិទីពីរគឺការចំណាយលើក្បាលធំសម្រាប់ hashing ។ គុណវិបត្តិនេះមិនច្បាស់ទេ។ ហើយសម្រាប់ពួកយើងវាក៏មិនច្បាស់ដែរ ដូច្នេះដំបូងឡើយនៅក្នុង VictoriaMetrics ការអនុវត្តចំនុចប្រសព្វគឺតាមរយៈផែនទី។ ប៉ុន្តែបន្ទាប់មក ការធ្វើប្រវត្តិរូបបានបង្ហាញថា ពេលវេលាដំណើរការសំខាន់ត្រូវបានចំណាយលើការសរសេរទៅកាន់ផែនទី និងពិនិត្យមើលវត្តមានតម្លៃនៅក្នុងផែនទីនេះ។
ហេតុអ្វីបានជា CPU ខ្ជះខ្ជាយពេលវេលានៅកន្លែងទាំងនេះ? ដោយសារតែ Go ធ្វើប្រតិបត្តិការ hashing នៅលើបន្ទាត់ទាំងនេះ។ នោះគឺវាគណនា hash នៃ key ដើម្បីចូលប្រើវានៅលិបិក្រមដែលបានផ្តល់ឱ្យនៅក្នុង HashMap ។ ប្រតិបត្តិការគណនា hash ត្រូវបានបញ្ចប់ក្នុងរយៈពេលរាប់សិប nanoseconds ។ នេះគឺយឺតសម្រាប់ VictoriaMetrics ។
ខ្ញុំបានសម្រេចចិត្តអនុវត្ត bitset ដែលត្រូវបានធ្វើឱ្យប្រសើរឡើងជាពិសេសសម្រាប់ករណីនេះ។ នេះជាចំនុចប្រសព្វនៃបំណែកពីរឥឡូវនេះមើលទៅ នៅទីនេះយើងបង្កើតសំណុំប៊ីត។ យើងបន្ថែមធាតុពីចំណិតទីមួយទៅវា។ បន្ទាប់មកយើងពិនិត្យមើលវត្តមានរបស់ធាតុទាំងនេះនៅក្នុងផ្នែកទីពីរ។ ហើយបន្ថែមពួកវាទៅក្នុងលទ្ធផល។ នោះគឺវាស្ទើរតែមិនខុសពីឧទាហរណ៍មុនទេ។ រឿងតែមួយគត់នៅទីនេះគឺថាយើងបានជំនួសការចូលប្រើផែនទីជាមួយនឹងមុខងារផ្ទាល់ខ្លួន add
и has
.
នៅក្រឡេកមើលដំបូង វាហាក់បីដូចជាវាដំណើរការយឺតជាង ប្រសិនបើពីមុនផែនទីស្តង់ដារត្រូវបានប្រើនៅទីនោះ ហើយបន្ទាប់មកមុខងារមួយចំនួនទៀតត្រូវបានហៅ ប៉ុន្តែទម្រង់បង្ហាញថាវត្ថុនេះដំណើរការលឿនជាងផែនទីស្តង់ដារ 10 ដងក្នុងករណី VictoriaMetrics ។
លើសពីនេះ វាប្រើប្រាស់អង្គចងចាំតិចជាងច្រើន បើប្រៀបធៀបទៅនឹងការអនុវត្តផែនទី។ ដោយសារតែយើងកំពុងរក្សាទុកប៊ីតនៅទីនេះជំនួសឱ្យតម្លៃប្រាំបីបៃ។
គុណវិបត្តិនៃការអនុវត្តនេះគឺថាវាមិនច្បាស់លាស់ មិនមែនជារឿងតូចតាចទេ។
គុណវិបត្តិមួយទៀតដែលមនុស្សជាច្រើនប្រហែលជាមិនកត់សំគាល់នោះគឺថាការអនុវត្តនេះប្រហែលជាមិនដំណើរការល្អទេក្នុងករណីខ្លះ។ នោះគឺវាត្រូវបានធ្វើឱ្យប្រសើរសម្រាប់ករណីជាក់លាក់មួយ សម្រាប់ករណីនៃចំណុចប្រសព្វនៃលេខសម្គាល់ស៊េរីពេលវេលា VictoriaMetrics ។ នេះមិនមានន័យថាវាសាកសមសម្រាប់គ្រប់ករណីទាំងអស់នោះទេ។ ប្រសិនបើវាត្រូវបានប្រើប្រាស់មិនត្រឹមត្រូវ យើងនឹងមិនទទួលបានការកើនឡើងនៃដំណើរការនោះទេ ប៉ុន្តែមានកំហុសចេញពីអង្គចងចាំ និងការថយចុះនៃដំណើរការ។
ចូរយើងពិចារណាលើការអនុវត្តរចនាសម្ព័ន្ធនេះ។ ប្រសិនបើអ្នកចង់មើល វាមានទីតាំងនៅក្នុងប្រភព VictoriaMetrics នៅក្នុងថតឯកសារ timeseries_id
គឺជាតម្លៃ 64 ប៊ីត ដែល 32 ប៊ីតដំបូងគឺថេរជាមូលដ្ឋាន ហើយមានតែការផ្លាស់ប្តូរ 32 ប៊ីតចុងក្រោយប៉ុណ្ណោះ។
រចនាសម្ព័ន្ធទិន្នន័យនេះមិនត្រូវបានរក្សាទុកនៅលើថាសទេ វាដំណើរការតែនៅក្នុងអង្គចងចាំប៉ុណ្ណោះ។
នេះគឺជា API របស់វា។ វាមិនស្មុគស្មាញខ្លាំងទេ។ API ត្រូវបានសម្របតាមឧទាហរណ៍ជាក់លាក់នៃការប្រើ VictoriaMetrics។ នោះគឺមិនមានមុខងារដែលមិនចាំបាច់នៅទីនេះទេ។ នេះគឺជាមុខងារដែលត្រូវបានប្រើប្រាស់យ៉ាងច្បាស់លាស់ដោយ VictoriaMetrics។
មានមុខងារ add
ដែលបន្ថែមតម្លៃថ្មី។ មានមុខងារមួយ។ has
ដែលពិនិត្យមើលតម្លៃថ្មី។ ហើយមានមុខងារមួយ។ del
ដែលយកតម្លៃចេញ។ មានមុខងារជំនួយ len
ដែលត្រឡប់ទំហំនៃសំណុំ។ មុខងារ clone
ក្លូនច្រើន។ និងមុខងារ appendto
បំប្លែងសំណុំនេះទៅជាចំណិត timeseries_ids
.
នេះគឺជាអ្វីដែលការអនុវត្តរចនាសម្ព័ន្ធទិន្នន័យនេះមើលទៅដូច។ ឈុតមានពីរធាតុ៖
-
ItemsCount
គឺជាវាលជំនួយដើម្បីត្រឡប់ចំនួនធាតុនៅក្នុងសំណុំមួយយ៉ាងរហ័ស។ វាអាចធ្វើដោយគ្មានវាលជំនួយនេះ ប៉ុន្តែវាត្រូវតែបន្ថែមនៅទីនេះ ព្រោះ VictoriaMetrics តែងតែសួរអំពីប្រវែងប៊ីតនៅក្នុងក្បួនដោះស្រាយរបស់វា។ -
វាលទីពីរគឺ
buckets
. នេះគឺជាបំណែកនៃរចនាសម្ព័ន្ធbucket32
. រចនាសម្ព័ន្ធនីមួយៗរក្សាទុកhi
វាល។ ទាំងនេះគឺជា 32 ប៊ីតខាងលើ។ និងពីរចំណិត -b16his
иbuckets
ពីbucket16
រចនាសម្ព័ន្ធ។
កំពូល 16 ប៊ីតនៃផ្នែកទីពីរនៃរចនាសម្ព័ន្ធ 64 ប៊ីតត្រូវបានរក្សាទុកនៅទីនេះ។ ហើយនៅទីនេះប៊ីតត្រូវបានរក្សាទុកសម្រាប់ 16 ប៊ីតទាបនៃបៃនីមួយៗ។
Bucket64
មានអារេ uint64
. ប្រវែងត្រូវបានគណនាដោយប្រើថេរទាំងនេះ។ ក្នុងមួយ bucket16
អតិបរមាអាចរក្សាទុកបាន។ 2^16=65536
ប៊ីត។ ប្រសិនបើអ្នកបែងចែកវាដោយ 8 នោះវាគឺ 8 គីឡូបៃ។ ប្រសិនបើអ្នកចែកដោយ 8 ម្តងទៀតវាគឺ 1000 uint64
អត្ថន័យ។ នោះគឺជា Bucket16
- នេះគឺជារចនាសម្ព័ន្ធ 8 គីឡូបៃរបស់យើង។
សូមក្រឡេកមើលពីរបៀបដែលវិធីសាស្រ្តមួយនៃរចនាសម្ព័ន្ធនេះសម្រាប់ការបន្ថែមតម្លៃថ្មីត្រូវបានអនុវត្ត។
វាទាំងអស់ចាប់ផ្តើមជាមួយ uint64
អត្ថន័យ។ យើងគណនាខាងលើ 32 ប៊ីត យើងគណនា 32 ប៊ីតទាប។ ចូរយើងឆ្លងកាត់អ្វីៗទាំងអស់។ buckets
. យើងប្រៀបធៀបកំពូល 32 ប៊ីតនៅក្នុងធុងនីមួយៗជាមួយនឹងតម្លៃដែលត្រូវបានបន្ថែម។ ហើយប្រសិនបើពួកគេត្រូវគ្នានោះយើងហៅមុខងារ add
នៅក្នុងរចនាសម្ព័ន្ធ b32 buckets
. ហើយបន្ថែម 32 ប៊ីតទាបនៅទីនោះ។ ហើយប្រសិនបើវាត្រឡប់មកវិញ true
នោះមានន័យថា យើងបានបន្ថែមតម្លៃនៅទីនោះ ហើយយើងមិនមានតម្លៃបែបនេះទេ។ ប្រសិនបើវាត្រឡប់មកវិញ false
បន្ទាប់មកអត្ថន័យបែបនេះមានរួចហើយ។ បន្ទាប់មកយើងបង្កើនចំនួនធាតុនៅក្នុងរចនាសម្ព័ន្ធ។
ប្រសិនបើយើងរកមិនឃើញអ្នកត្រូវការ bucket
ជាមួយនឹងតម្លៃខ្ពស់ដែលត្រូវការបន្ទាប់មកយើងហៅមុខងារ addAlloc
ដែលនឹងផលិតថ្មីមួយ bucket
បន្ថែមវាទៅរចនាសម្ព័ន្ធធុង។
នេះគឺជាការអនុវត្តមុខងារ b32.add
. វាស្រដៀងនឹងការអនុវត្តពីមុន។ យើងគណនា 16 ប៊ីតដ៏សំខាន់បំផុត 16 ប៊ីតដែលសំខាន់តិចបំផុត។
បន្ទាប់មកយើងឆ្លងកាត់ 16 ប៊ីតខាងលើទាំងអស់។ យើងរកឃើញការប្រកួត។ ហើយប្រសិនបើមានការផ្គូផ្គង យើងហៅវិធីសាស្ត្របន្ថែម ដែលយើងនឹងពិចារណានៅទំព័របន្ទាប់សម្រាប់ bucket16
.
ហើយនេះគឺជាកម្រិតទាបបំផុត ដែលគួរតែត្រូវបានធ្វើឱ្យប្រសើរតាមដែលអាចធ្វើទៅបាន។ យើងគណនាសម្រាប់ uint64
តម្លៃ id នៅក្នុង slice bit និងផងដែរ។ bitmask
. នេះគឺជារបាំងសម្រាប់តម្លៃ 64 ប៊ីតដែលបានផ្តល់ឱ្យ ដែលអាចត្រូវបានប្រើដើម្បីពិនិត្យមើលវត្តមានរបស់ប៊ីតនេះ ឬកំណត់វា។ យើងពិនិត្យមើលថាតើប៊ីតនេះត្រូវបានកំណត់ និងកំណត់វា ហើយត្រឡប់វត្តមានវិញ។ នេះគឺជាការអនុវត្តរបស់យើង ដែលអនុញ្ញាតឱ្យយើងបង្កើនល្បឿនប្រតិបត្តិការនៃលេខសម្គាល់ប្រសព្វនៃស៊េរីពេលវេលាចំនួន 10 ដងបើប្រៀបធៀបទៅនឹងផែនទីធម្មតា។
បន្ថែមពីលើការបង្កើនប្រសិទ្ធភាពនេះ VictoriaMetrics មានការបង្កើនប្រសិទ្ធភាពជាច្រើនទៀត។ ភាគច្រើននៃការបង្កើនប្រសិទ្ធភាពទាំងនេះត្រូវបានបន្ថែមសម្រាប់ហេតុផលមួយ ប៉ុន្តែបន្ទាប់ពីទម្រង់កូដនៅក្នុងផលិតកម្ម។
នេះគឺជាច្បាប់ចម្បងនៃការបង្កើនប្រសិទ្ធភាព - កុំបន្ថែមការបង្កើនប្រសិទ្ធភាពដោយសន្មត់ថានឹងមានឧបសគ្គនៅទីនេះ ព្រោះវាប្រហែលជាមិនមានបញ្ហាកកស្ទះនៅទីនោះទេ។ ការបង្កើនប្រសិទ្ធភាពជាធម្មតាធ្វើឱ្យខូចគុណភាពនៃកូដ។ ដូច្នេះវាមានតម្លៃក្នុងការបង្កើនប្រសិទ្ធភាពតែបន្ទាប់ពីទម្រង់និងនិយមនៅក្នុងផលិតកម្ម ដូច្នេះនេះគឺជាទិន្នន័យពិត។ ប្រសិនបើនរណាម្នាក់ចាប់អារម្មណ៍ អ្នកអាចមើលកូដប្រភព VictoriaMetrics និងស្វែងរកការបង្កើនប្រសិទ្ធភាពផ្សេងទៀតដែលមាននៅទីនោះ។
ខ្ញុំមានសំណួរអំពីប៊ីតធីត។ ស្រដៀងគ្នានឹងការអនុវត្តវ៉ិចទ័រ C ++ ដែលបានធ្វើឱ្យប្រសើរឡើងនូវសំណុំប៊ីត។ តើអ្នកយកការអនុវត្តពីទីនោះទេ?
ទេមិនមែនមកពីទីនោះទេ។ នៅពេលអនុវត្តសំណុំប៊ីតនេះ ខ្ញុំត្រូវបានណែនាំដោយចំណេះដឹងអំពីរចនាសម្ព័ន្ធនៃលេខសម្គាល់ទាំងនេះ ដែលត្រូវបានប្រើនៅក្នុង VictoriaMetrics ។ ហើយរចនាសម្ព័ន្ធរបស់ពួកគេគឺដូចជា 32 ប៊ីតខាងលើគឺថេរជាមូលដ្ឋាន។ 32 ប៊ីតទាបអាចផ្លាស់ប្តូរបាន។ កម្រិតទាបជាងបន្តិច វាអាចផ្លាស់ប្តូរបានញឹកញាប់។ ដូច្នេះការអនុវត្តនេះត្រូវបានធ្វើឱ្យប្រសើរជាពិសេសសម្រាប់រចនាសម្ព័ន្ធទិន្នន័យនេះ។ ការអនុវត្ត C++ តាមដែលខ្ញុំដឹងគឺត្រូវបានធ្វើឱ្យប្រសើរឡើងសម្រាប់ករណីទូទៅ។ ប្រសិនបើអ្នកបង្កើនប្រសិទ្ធភាពសម្រាប់ករណីទូទៅ នេះមានន័យថាវានឹងមិនល្អបំផុតសម្រាប់ករណីជាក់លាក់នោះទេ។
ខ្ញុំក៏ណែនាំអ្នកឱ្យមើលរបាយការណ៍របស់ Alexey Milovid ។ ប្រហែលមួយខែមុនគាត់បាននិយាយអំពីការបង្កើនប្រសិទ្ធភាពនៅក្នុង ClickHouse សម្រាប់ឯកទេសជាក់លាក់។ គាត់គ្រាន់តែនិយាយថា នៅក្នុងករណីទូទៅ ការអនុវត្ត C++ ឬការអនុវត្តផ្សេងទៀតត្រូវបានកែសម្រួលដើម្បីដំណើរការបានល្អជាមធ្យមនៅក្នុងមន្ទីរពេទ្យ។ វាអាចដំណើរការអាក្រក់ជាងការអនុវត្តជាក់ស្តែងដូចជាយើង ដែលយើងដឹងថា 32 ប៊ីតកំពូលភាគច្រើនគឺថេរ។
ខ្ញុំមានសំណួរទីពីរ។ តើអ្វីជាភាពខុសគ្នាជាមូលដ្ឋានពី InfluxDB?
មានភាពខុសគ្នាជាមូលដ្ឋានជាច្រើន។ នៅក្នុងលក្ខខណ្ឌនៃការអនុវត្តនិងការប្រើប្រាស់អង្គចងចាំ InfluxDB នៅក្នុងការធ្វើតេស្តបង្ហាញពីការប្រើប្រាស់អង្គចងចាំច្រើនជាង 10 ដងសម្រាប់ស៊េរីពេលវេលា cardinality ខ្ពស់នៅពេលដែលអ្នកមានវាច្រើនឧទាហរណ៍រាប់លាន។ ឧទាហរណ៍ VictoriaMetrics ប្រើប្រាស់ 1 GB ក្នុងមួយលានជួរសកម្ម ខណៈ InfluxDB ប្រើប្រាស់ 10 GB ។ ហើយនោះជាភាពខុសគ្នាដ៏ធំមួយ។
ភាពខុសគ្នាជាមូលដ្ឋានទីពីរគឺថា InfluxDB មានភាសាសំណួរចម្លែក - Flux និង InfluxQL ។ ពួកវាមិនងាយស្រួលសម្រាប់ធ្វើការជាមួយស៊េរីពេលវេលាទេបើប្រៀបធៀបទៅនឹង
ហើយភាពខុសគ្នាមួយទៀតគឺថា InfluxDB មានគំរូទិន្នន័យចម្លែកបន្តិច ដែលបន្ទាត់នីមួយៗអាចរក្សាទុកវាលជាច្រើនជាមួយនឹងសំណុំនៃស្លាកផ្សេងៗគ្នា។ បន្ទាត់ទាំងនេះត្រូវបានបែងចែកបន្ថែមទៀតទៅជាតារាងផ្សេងៗ។ ផលវិបាកបន្ថែមទាំងនេះធ្វើឱ្យស្មុគស្មាញដល់ការងារជាបន្តបន្ទាប់ជាមួយមូលដ្ឋានទិន្នន័យនេះ។ វាពិបាកក្នុងការគាំទ្រនិងយល់។
នៅក្នុង VictoriaMetrics អ្វីៗគឺសាមញ្ញជាង។ នៅទីនោះ ស៊េរីពេលវេលានីមួយៗគឺជាតម្លៃគន្លឹះ។ តម្លៃគឺជាសំណុំនៃចំណុច - (timestamp, value)
ហើយគន្លឹះគឺសំណុំ label=value
. មិនមានការបែងចែករវាងវាល និងការវាស់វែងទេ។ វាអនុញ្ញាតឱ្យអ្នកជ្រើសរើសទិន្នន័យណាមួយ ហើយបន្ទាប់មកបញ្ចូលគ្នា បន្ថែម ដក គុណ ចែក មិនដូច InfluxDB ដែលការគណនារវាងជួរផ្សេងគ្នានៅតែមិនត្រូវបានអនុវត្តដូចដែលខ្ញុំដឹង។ ទោះបីជាពួកគេត្រូវបានអនុវត្តក៏ដោយវាពិបាកណាស់អ្នកត្រូវសរសេរកូដច្រើន។
ខ្ញុំមានសំណួរបញ្ជាក់។ តើខ្ញុំយល់ត្រឹមត្រូវទេថាមានបញ្ហាមួយចំនួនដែលអ្នកបាននិយាយ ថាសន្ទស្សន៍ដាក់បញ្ច្រាសនេះមិនសមនឹងអង្គចងចាំទេ ដូច្នេះមានការចែកភាគនៅទីនោះ?
ដំបូង ខ្ញុំបានបង្ហាញការអនុវត្តដោយឆោតល្ងង់នៃសន្ទស្សន៍បញ្ច្រាសនៅលើផែនទី Go ស្តង់ដារ។ ការអនុវត្តនេះមិនស័ក្តិសមសម្រាប់មូលដ្ឋានទិន្នន័យទេ ដោយសារសន្ទស្សន៍ដាក់បញ្ច្រាសនេះមិនត្រូវបានរក្សាទុកក្នុងថាស ហើយមូលដ្ឋានទិន្នន័យត្រូវតែរក្សាទុកក្នុងថាស ដូច្នេះទិន្នន័យនេះនៅតែមាននៅពេលចាប់ផ្តើមឡើងវិញ។ នៅក្នុងការអនុវត្តនេះ នៅពេលអ្នកចាប់ផ្តើមកម្មវិធីឡើងវិញ សន្ទស្សន៍ដាក់បញ្ច្រាសរបស់អ្នកនឹងរលាយបាត់។ ហើយអ្នកនឹងបាត់បង់សិទ្ធិចូលប្រើទិន្នន័យទាំងអស់ ព្រោះអ្នកនឹងមិនអាចស្វែងរកវាបានទេ។
សួស្តី! អរគុណសម្រាប់របាយការណ៍! ខ្ញុំឈ្មោះ Pavel ។ ខ្ញុំមកពី Wildberries ។ ខ្ញុំមានសំណួរមួយចំនួនសម្រាប់អ្នក។ សំណួរទីមួយ។ តើអ្នកគិតថាប្រសិនបើអ្នកបានជ្រើសរើសគោលការណ៍ផ្សេងនៅពេលបង្កើតស្ថាបត្យកម្មនៃកម្មវិធីរបស់អ្នក ហើយបែងចែកទិន្នន័យតាមពេលវេលា នោះប្រហែលជាអ្នកប្រហែលជាអាចប្រសព្វទិន្នន័យនៅពេលស្វែងរក ដោយផ្អែកលើការពិតដែលថាភាគថាសមួយមានទិន្នន័យសម្រាប់មួយ។ រយៈពេល នោះគឺក្នុងចន្លោះពេលមួយ ហើយអ្នកនឹងមិនមានការព្រួយបារម្ភអំពីការពិតដែលថាបំណែករបស់អ្នកត្រូវបានរាយប៉ាយខុសគ្នា? សំណួរទី 2 - ចាប់តាំងពីអ្នកកំពុងអនុវត្តក្បួនដោះស្រាយស្រដៀងគ្នាជាមួយប៊ីតធីត និងអ្វីៗផ្សេងទៀត ប្រហែលជាអ្នកបានព្យាយាមប្រើការណែនាំរបស់ខួរក្បាល? ប្រហែលជាអ្នកបានព្យាយាមបង្កើនប្រសិទ្ធភាពបែបនេះ?
ខ្ញុំនឹងឆ្លើយទីពីរភ្លាមៗ។ យើងមិនទាន់ឈានដល់ចំណុចនោះនៅឡើយទេ។ ប៉ុន្តែប្រសិនបើចាំបាច់យើងនឹងទៅដល់ទីនោះ។ ហើយទីមួយ សំណួរសួរថាម៉េច?
អ្នកបានពិភាក្សាអំពីសេណារីយ៉ូពីរ។ ហើយពួកគេបាននិយាយថាពួកគេជ្រើសរើសទីពីរដោយមានការអនុវត្តស្មុគស្មាញជាង។ ហើយពួកគេមិនចូលចិត្តទីមួយទេ ដែលទិន្នន័យត្រូវបានបែងចែកតាមពេលវេលា។
បាទ។ ក្នុងករណីដំបូង បរិមាណសរុបនៃលិបិក្រមនឹងធំជាង ពីព្រោះនៅក្នុងភាគថាសនីមួយៗ យើងនឹងត្រូវរក្សាទុកទិន្នន័យស្ទួនសម្រាប់ស៊េរីពេលវេលាទាំងនោះដែលបន្តតាមរយៈភាគថាសទាំងអស់នេះ។ ហើយប្រសិនបើអត្រានៃស៊េរីពេលវេលារបស់អ្នកមានទំហំតូច ពោលគឺស៊េរីដូចគ្នាត្រូវបានប្រើប្រាស់ឥតឈប់ឈរ នោះក្នុងករណីដំបូង យើងនឹងបាត់បង់កាន់តែច្រើននៅក្នុងទំហំថាសដែលបានកាន់កាប់បើប្រៀបធៀបទៅនឹងករណីទីពីរ។
ដូច្នេះហើយ - បាទ ការបែងចែកពេលវេលាគឺជាជម្រើសដ៏ល្អ។ Prometheus ប្រើវា។ ប៉ុន្តែ Prometheus មានគុណវិបត្តិមួយទៀត។ នៅពេលបញ្ចូលគ្នានូវបំណែកទិន្នន័យទាំងនេះ វាចាំបាច់ត្រូវរក្សាទុកព័ត៌មានមេតានៃអង្គចងចាំសម្រាប់ស្លាក និងតារាងពេលវេលាទាំងអស់។ ដូច្នេះ ប្រសិនបើបំណែកនៃទិន្នន័យដែលវាបញ្ចូលចូលគ្នាមានទំហំធំ នោះការប្រើប្រាស់អង្គចងចាំកើនឡើងយ៉ាងខ្លាំងកំឡុងពេលបញ្ចូលគ្នា មិនដូច VictoriaMetrics ទេ។ នៅពេលបញ្ចូលគ្នា VictoriaMetrics មិនប្រើប្រាស់អង្គចងចាំទាល់តែសោះ មានតែពីរបីគីឡូបៃប៉ុណ្ណោះដែលត្រូវបានប្រើប្រាស់ ដោយមិនគិតពីទំហំនៃបំណែកទិន្នន័យដែលបានបញ្ចូលគ្នានោះទេ។
ក្បួនដោះស្រាយដែលអ្នកកំពុងប្រើប្រើអង្គចងចាំ។ វាសម្គាល់ស្លាកលេខដែលមានតម្លៃ។ ហើយវិធីនេះ អ្នកពិនិត្យមើលវត្តមានដែលបានផ្គូផ្គងនៅក្នុងអារេទិន្នន័យមួយ និងក្នុងអារេផ្សេងទៀត។ ហើយអ្នកយល់ថាតើប្រសព្វបានកើតឡើងឬអត់។ ជាធម្មតា មូលដ្ឋានទិន្នន័យអនុវត្តទស្សន៍ទ្រនិច និងកម្មវិធីរំលឹកឡើងវិញ ដែលរក្សាទុកមាតិកាបច្ចុប្បន្នរបស់ពួកគេ និងដំណើរការតាមរយៈទិន្នន័យដែលបានតម្រៀប ដោយសារភាពស្មុគស្មាញសាមញ្ញនៃប្រតិបត្តិការទាំងនេះ។
ហេតុអ្វីបានជាយើងមិនប្រើទស្សន៍ទ្រនិចដើម្បីឆ្លងកាត់ទិន្នន័យ?
បាទ។
យើងរក្សាទុកជួរដែលបានតម្រៀបក្នុង LevelDB ឬបញ្ចូលគ្នា។ យើងអាចរំកិលទស្សន៍ទ្រនិច ហើយស្វែងរកចំនុចប្រសព្វ។ ហេតុអ្វីបានជាយើងមិនប្រើវា? ដោយសារតែវាយឺត។ ដោយសារតែទស្សន៍ទ្រនិចមានន័យថាអ្នកត្រូវហៅមុខងារសម្រាប់បន្ទាត់នីមួយៗ។ ការហៅមុខងារគឺ 5 ណាណូវិនាទី។ ហើយប្រសិនបើអ្នកមាន 100 បន្ទាត់ នោះវាប្រែថាយើងចំណាយពេលកន្លះវិនាទីគ្រាន់តែហៅមុខងារ។
មានរឿងបែបនេះ បាទ។ ហើយសំណួរចុងក្រោយរបស់ខ្ញុំ។ សំណួរអាចស្តាប់ទៅចម្លែកបន្តិច។ ហេតុអ្វីបានជាវាមិនអាចអានការសរុបចាំបាច់ទាំងអស់នៅពេលទិន្នន័យមកដល់ ហើយរក្សាទុកពួកវាក្នុងទម្រង់ដែលត្រូវការ? ហេតុអ្វីបានជារក្សាទុកបរិមាណដ៏ធំនៅក្នុងប្រព័ន្ធមួយចំនួនដូចជា VictoriaMetrics, ClickHouse ជាដើម ហើយបន្ទាប់មកចំណាយពេលច្រើនលើពួកវា?
ខ្ញុំនឹងលើកឧទាហរណ៍មួយ ដើម្បីអោយវាកាន់តែច្បាស់។ ចូរនិយាយថាតើឧបករណ៍វាស់ល្បឿនប្រដាប់ក្មេងលេងតូចដំណើរការយ៉ាងដូចម្តេច? វាកត់ត្រាចម្ងាយដែលអ្នកបានធ្វើដំណើរគ្រប់ពេល ដោយបន្ថែមវាទៅតម្លៃមួយ និងលើកទីពីរ - ពេលវេលា។ និងបែងចែក។ និងទទួលបានល្បឿនមធ្យម។ អ្នកអាចធ្វើអំពីរឿងដូចគ្នា។ បន្ថែមអង្គហេតុចាំបាច់ទាំងអស់ភ្លាមៗ។
មិនអីទេ ខ្ញុំយល់ពីសំណួរ។ ឧទាហរណ៍របស់អ្នកមានកន្លែង។ ប្រសិនបើអ្នកដឹងពីអ្វីដែលសរុបដែលអ្នកត្រូវការនោះ នេះគឺជាការអនុវត្តដ៏ល្អបំផុត។ ប៉ុន្តែបញ្ហាគឺថាមនុស្សរក្សាទុកម៉ែត្រទាំងនេះ ទិន្នន័យមួយចំនួននៅក្នុង ClickHouse ហើយពួកគេមិនទាន់ដឹងពីរបៀបដែលពួកគេនឹងប្រមូលផ្តុំ និងត្រងពួកវានៅពេលអនាគត ដូច្នេះពួកគេត្រូវតែរក្សាទុកទិន្នន័យឆៅទាំងអស់។ ប៉ុន្តែប្រសិនបើអ្នកដឹងថាអ្នកត្រូវគណនាអ្វីមួយជាមធ្យម នោះហេតុអ្វីមិនគណនាវាជំនួសឱ្យការរក្សាទុក bunch នៃតម្លៃឆៅនៅទីនោះ? ប៉ុន្តែនេះគ្រាន់តែប្រសិនបើអ្នកដឹងច្បាស់ពីអ្វីដែលអ្នកត្រូវការ។
ដោយវិធីនេះ មូលដ្ឋានទិន្នន័យសម្រាប់ការរក្សាទុកស៊េរីពេលវេលាគាំទ្រការរាប់ចំនួនសរុប។ ឧទាហរណ៍ Prometheus គាំទ្រ
ជាឧទាហរណ៍ ក្នុងការងារមុនរបស់ខ្ញុំ ខ្ញុំត្រូវរាប់ចំនួនព្រឹត្តិការណ៍នៅក្នុងបង្អួចរអិលក្នុងរយៈពេលមួយម៉ោងចុងក្រោយ។ បញ្ហាគឺថាខ្ញុំត្រូវធ្វើការអនុវត្តផ្ទាល់ខ្លួននៅក្នុង Go ពោលគឺសេវាកម្មសម្រាប់រាប់វត្ថុនេះ។ សេវាកម្មនេះនៅទីបំផុតមិនមែនជារឿងតូចតាចទេ ព្រោះវាពិបាកក្នុងការគណនា។ ការអនុវត្តអាចមានលក្ខណៈសាមញ្ញ ប្រសិនបើអ្នកត្រូវការរាប់ចំនួនសរុបនៅចន្លោះពេលកំណត់។ ប្រសិនបើអ្នកចង់រាប់ព្រឹត្តិការណ៍នៅក្នុងបង្អួចរអិល នោះវាមិនសាមញ្ញដូចដែលវាហាក់ដូចជានោះទេ។ ខ្ញុំគិតថាវាមិនទាន់ត្រូវបានអនុវត្តនៅក្នុង ClickHouse ឬនៅក្នុងមូលដ្ឋានទិន្នន័យដងទេព្រោះវាមានការលំបាកក្នុងការអនុវត្ត។
និងសំណួរមួយទៀត។ យើងគ្រាន់តែនិយាយអំពីកម្រិតមធ្យមប៉ុណ្ណោះ ហើយខ្ញុំចាំបានថា មានពេលមួយដូចជា Graphite ដែលមាន backend កាបូន។ ហើយគាត់បានដឹងពីរបៀបកាត់បន្ថយទិន្នន័យចាស់ ពោលគឺទុកមួយចំណុចក្នុងមួយនាទី មួយចំណុចក្នុងមួយម៉ោង។ល។ ជាគោលការណ៍ វាពិតជាងាយស្រួលណាស់ ប្រសិនបើយើងត្រូវការទិន្នន័យឆៅ ទាក់ទងគ្នារយៈពេលមួយខែ និងអ្វីៗផ្សេងទៀតអាច ត្រូវបានស្តើងចេញ។ ប៉ុន្តែ Prometheus និង VictoriaMetrics មិនគាំទ្រមុខងារនេះទេ។ តើវាមានគម្រោងគាំទ្រវាទេ? បើមិនដូច្នេះទេ?
សូមអរគុណចំពោះសំណួរ។ អ្នកប្រើប្រាស់របស់យើងសួរសំណួរនេះជាទៀងទាត់។ ពួកគេសួរថាតើនៅពេលណាដែលយើងនឹងបន្ថែមការគាំទ្រសម្រាប់ការចុះគំរូ។ មានបញ្ហាជាច្រើននៅទីនេះ។ ទីមួយអ្នកប្រើប្រាស់គ្រប់រូបយល់ downsampling
អ្វីដែលខុសគ្នា៖ នរណាម្នាក់ចង់ទទួលបានចំណុចបំពានណាមួយនៅលើចន្លោះពេលដែលបានផ្តល់ឱ្យ អ្នកណាម្នាក់ចង់បានតម្លៃអតិបរមា អប្បបរមា និងមធ្យម។ ប្រសិនបើប្រព័ន្ធជាច្រើនសរសេរទិន្នន័យទៅក្នុងមូលដ្ឋានទិន្នន័យរបស់អ្នក នោះអ្នកមិនអាចបញ្ចូលវាទាំងអស់គ្នាបានទេ។ វាអាចថាប្រព័ន្ធនីមួយៗត្រូវការការស្តើងខុសៗគ្នា។ ហើយនេះគឺជាការលំបាកក្នុងការអនុវត្ត។
ហើយរឿងទីពីរគឺថា VictoriaMetrics ដូចជា ClickHouse ត្រូវបានធ្វើឱ្យប្រសើរសម្រាប់ធ្វើការជាមួយបរិមាណដ៏ធំនៃទិន្នន័យឆៅ ដូច្នេះវាអាចរុញបន្ទាត់រាប់ពាន់លានក្នុងរយៈពេលតិចជាងមួយវិនាទី ប្រសិនបើអ្នកមានស្នូលជាច្រើននៅក្នុងប្រព័ន្ធរបស់អ្នក។ ការស្កេនពិន្ទុស៊េរីពេលវេលានៅក្នុង VictoriaMetrics - 50 ពិន្ទុក្នុងមួយវិនាទីក្នុងមួយស្នូល។ ហើយការអនុវត្តនេះធ្វើមាត្រដ្ឋានទៅស្នូលដែលមានស្រាប់។ នោះគឺប្រសិនបើអ្នកមាន 000 cores ជាឧទាហរណ៍ អ្នកនឹងស្កេនមួយពាន់លានពិន្ទុក្នុងមួយវិនាទី។ ហើយទ្រព្យសម្បត្តិរបស់ VictoriaMetrics និង ClickHouse នេះកាត់បន្ថយតម្រូវការសម្រាប់ការធ្លាក់ចុះ។
លក្ខណៈពិសេសមួយទៀតគឺថា VictoriaMetrics មានប្រសិទ្ធភាពបង្ហាប់ទិន្នន័យនេះ។ ការបង្ហាប់ជាមធ្យមក្នុងផលិតកម្មគឺពី 0,4 ទៅ 0,8 បៃក្នុងមួយចំណុច។ ចំណុចនីមួយៗគឺជាត្រាពេលវេលា + តម្លៃ។ ហើយវាត្រូវបានបង្ហាប់ទៅជាតិចជាងមួយបៃជាមធ្យម។
លោក Sergey ។ ខ្ញុំមានសំណួរមួយ។ តើពេលវេលាកត់ត្រាអប្បបរមាគឺជាអ្វី?
មួយមិល្លីវិនាទី។ ថ្មីៗនេះ យើងមានការសន្ទនាជាមួយអ្នកបង្កើតមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលាផ្សេងទៀត។ ពេលវេលាអប្បបរមារបស់ពួកគេគឺមួយវិនាទី។ ហើយនៅក្នុង Graphite ជាឧទាហរណ៍ វាក៏មានមួយវិនាទីផងដែរ។ នៅក្នុង OpenTSDB វាក៏មានរយៈពេលមួយវិនាទីផងដែរ។ InfluxDB មានភាពជាក់លាក់ nanosecond ។ នៅក្នុង VictoriaMetrics វាគឺមួយមិល្លីវិនាទី ពីព្រោះនៅក្នុង Prometheus វាគឺមួយមិល្លីវិនាទី។ ហើយ VictoriaMetrics ត្រូវបានបង្កើតឡើងដំបូងជាកន្លែងផ្ទុកពីចម្ងាយសម្រាប់ Prometheus ។ ប៉ុន្តែឥឡូវនេះវាអាចរក្សាទុកទិន្នន័យពីប្រព័ន្ធផ្សេងៗ។
មនុស្សដែលខ្ញុំនិយាយទៅនិយាយថាពួកគេមានភាពត្រឹមត្រូវពីទីពីរទៅវិនាទី - វាគ្រប់គ្រាន់សម្រាប់ពួកគេ ព្រោះវាអាស្រ័យលើប្រភេទទិន្នន័យដែលកំពុងត្រូវបានរក្សាទុកនៅក្នុងមូលដ្ឋានទិន្នន័យស៊េរីពេលវេលា។ ប្រសិនបើនេះជាទិន្នន័យ DevOps ឬទិន្នន័យពីហេដ្ឋារចនាសម្ព័ន្ធ ដែលអ្នកប្រមូលវានៅចន្លោះពេល 30 វិនាទីក្នុងមួយនាទី នោះភាពត្រឹមត្រូវទីពីរគឺគ្រប់គ្រាន់ អ្នកមិនត្រូវការអ្វីតិចជាងនេះទេ។ ហើយប្រសិនបើអ្នកប្រមូលទិន្នន័យនេះពីប្រព័ន្ធជួញដូរប្រេកង់ខ្ពស់ នោះអ្នកត្រូវការភាពត្រឹមត្រូវ nanosecond ។
ភាពត្រឹមត្រូវនៃមីលីវិនាទីនៅក្នុង VictoriaMetrics ក៏សមរម្យសម្រាប់ករណី DevOps ផងដែរ ហើយអាចសមរម្យសម្រាប់ករណីភាគច្រើនដែលខ្ញុំបានលើកឡើងនៅដើមរបាយការណ៍។ រឿងតែមួយគត់ដែលវាអាចមិនសមស្របគឺប្រព័ន្ធជួញដូរប្រេកង់ខ្ពស់។
សូមអរគុណ! និងសំណួរមួយទៀត។ តើអ្វីជាភាពឆបគ្នានៅក្នុង PromQL?
ភាពឆបគ្នាខាងក្រោយពេញលេញ។ VictoriaMetrics គាំទ្រ PromQL យ៉ាងពេញលេញ។ លើសពីនេះទៀតវាបន្ថែមមុខងារកម្រិតខ្ពស់បន្ថែមទៀតនៅក្នុង PromQL ដែលត្រូវបានគេហៅថា
ឆានែល Telegram
មានតែអ្នកប្រើប្រាស់ដែលបានចុះឈ្មោះប៉ុណ្ណោះដែលអាចចូលរួមក្នុងការស្ទង់មតិនេះ។
តើអ្វីដែលរារាំងអ្នកពីការប្តូរទៅ VictoriaMetrics ជាកន្លែងផ្ទុករយៈពេលវែងរបស់អ្នកសម្រាប់ Prometheus? (សរសេរក្នុងមតិ ខ្ញុំនឹងបន្ថែមវាទៅការស្ទង់មតិ))
-
71,4%ខ្ញុំមិនប្រើ Prometheus 5 ទេ។
-
28,6%មិនដឹងអំពី VictoriaMetrics2
អ្នកប្រើប្រាស់ 7 នាក់បានបោះឆ្នោត។ អ្នកប្រើប្រាស់ ១៤ នាក់ត្រូវបានហាមឃាត់។
ប្រភព: www.habr.com