ClickHouse/docs/fa/development/architecture.md
2020-04-04 12:15:31 +03:00

45 KiB
Raw Blame History

machine_translated machine_translated_rev toc_priority toc_title
true d734a8e46d 62 بررسی اجمالی از معماری کلیک

بررسی اجمالی از معماری کلیک

تاتر سندرم قبل از قاعدگی ستون گرا درست است. داده ها توسط ستون ها و در طول اجرای ارریس ذخیره می شود (بردارها و یا تکه های ستون). هر زمان ممکن, عملیات در ارریس اعزام, به جای در ارزش های فردی. این است که به نام “vectorized query execution,” و این کمک می کند کاهش هزینه پردازش داده های واقعی.

این ایده چیز جدیدی نیست. این قدمت به APL زبان برنامه نویسی و فرزندان خود را: A +, J, K و Q. برنامه نویسی مجموعه در پردازش داده های علمی استفاده می شود. نه این ایده چیزی جدید در پایگاه داده های رابطه ای است: مثلا در Vectorwise سیستم.

دو روش مختلف برای سرعت بخشیدن به پردازش پرس و جو وجود دارد: اجرای پرس و جو و تولید کد زمان اجرا. در حالت دوم حذف تمام تغییر ناپذیر و اعزام پویا. هیچ کدام از این روش ها به شدت بهتر از دیگری نیست. تولید کد زمان اجرا می تواند بهتر باشد زمانی که فیوز بسیاری از عملیات, در نتیجه به طور کامل با استفاده از واحد اعدام پردازنده و خط لوله. اجرای پرس و جو بردار می تواند کمتر عملی باشد زیرا شامل بردار موقت است که باید به حافظه پنهان نوشته شود و به عقب برگردد. اگر داده های موقت در کش ال 2 مناسب نیست, این موضوع می شود. اما اجرای پرس و جو بردار به راحتی با بهره گیری از قابلیت سیم کارت از پردازنده. یک مقاله پژوهشی نوشته شده توسط دوستان ما نشان می دهد که بهتر است به ترکیب هر دو روش. تاتر با استفاده از اجرای پرس و جو بردار و حمایت اولیه برای تولید کد زمان اجرا محدود کرده است.

ستونها

IColumn رابط برای نشان دادن ستون ها در حافظه (در واقع تکه های ستون) استفاده می شود. این رابط فراهم می کند روش های کمکی برای اجرای اپراتورهای مختلف رابطه ای. تقریبا تمام عملیات تغییر ناپذیر است: ستون اصلی را تغییر نمی دهند اما یک تغییر جدید ایجاد می کنند. برای مثال IColumn :: filter روش یک ماسک بایت فیلتر می پذیرد. این برای استفاده می شود WHERE و HAVING اپراتورهای رابطه. نمونه های اضافی: IColumn :: permute روش پشتیبانی ORDER BY این IColumn :: cut روش پشتیبانی LIMIT.

مختلف IColumn پیاده سازی (ColumnUInt8, ColumnString و به همین ترتیب) برای طرح حافظه ستون ها به عهده دارند. طرح حافظه معمولا یک مجموعه پیوسته است. برای نوع عدد صحیح ستون, این فقط یک مجموعه به هم پیوسته است, پسندیدن std :: vector. برای String و Array ستون ها, این دو بردار است: یکی برای همه عناصر مجموعه, به طور متناوب قرار داده شده, و یک ثانیه برای شیپور خاموشی به ابتدای هر مجموعه. همچنین وجود دارد ColumnConst که فروشگاه فقط یک ارزش در حافظه, اما به نظر می رسد مانند یک ستون.

زمینه

با این اوصاف, ممکن است برای کار با ارزش های فردی و همچنین. برای نشان دادن ارزش فردی Field استفاده شده است. Field فقط یک اتحادیه تبعیض UInt64, Int64, Float64, String و Array. IColumn دارد operator[] روش برای دریافت ارزش ازت به عنوان یک Field و insert روش برای اضافه کردن یک Field به پایان یک ستون. این روش ها بسیار موثر نیستند زیرا نیاز به برخورد موقت دارند Field اشیا به نمایندگی از ارزش فردی. روش های موثر تر مانند insertFrom, insertRangeFrom و به همین ترتیب.

Field اطلاعات کافی در مورد یک نوع داده خاص برای یک جدول ندارد. به عنوان مثال, UInt8, UInt16, UInt32 و UInt64 همه به عنوان نمایندگی UInt64 در یک Field.

انتزاعی نشتی

IColumn روش هایی برای تحولات رابطه ای مشترک داده ها دارد اما همه نیازها را نمی بینند. به عنوان مثال, ColumnUInt64 یک روش برای محاسبه مجموع دو ستون ندارد و ColumnString یک روش برای اجرای یک جستجو زیر رشته ندارد. این روال بی شماری در خارج از اجرا IColumn.

توابع مختلف در ستون ها را می توان در یک روش عمومی و غیر موثر استفاده کرد IColumn مواد و روش ها برای استخراج Field ارزش, و یا در یک راه تخصصی با استفاده از دانش طرح حافظه داخلی از داده ها در یک خاص IColumn اجرا کردن. این است که توسط توابع ریخته گری به خاص اجرا شده است IColumn نوع و مقابله با نمایندگی داخلی به طور مستقیم. به عنوان مثال, ColumnUInt64 دارد getData روشی که اشاره به مجموعه داخلی را برمی گرداند, سپس یک روال جداگانه می خواند و یا که مجموعه را پر می کند به طور مستقیم. ما “leaky abstractions” برای اجازه دادن به تخصص های موثر روال های مختلف.

انواع داده ها

IDataType مسئول سریالسازی و deserialization: برای خواندن و نوشتن تکه های ستون یا فردی مقادیر دودویی یا به صورت متن. IDataType به طور مستقیم به انواع داده ها در جداول مربوط. مثلا, وجود دارد DataTypeUInt32, DataTypeDateTime, DataTypeString و به همین ترتیب.

IDataType و IColumn فقط شل به یکدیگر مربوط. انواع داده های مختلف را می توان در حافظه توسط همان نشان داده شده است IColumn پیاده سازی. به عنوان مثال, DataTypeUInt32 و DataTypeDateTime هر دو توسط نمایندگی ColumnUInt32 یا ColumnConstUInt32. علاوه بر این, همان نوع داده را می توان با مختلف نشان IColumn پیاده سازی. به عنوان مثال, DataTypeUInt8 می توان با نمایندگی ColumnUInt8 یا ColumnConstUInt8.

IDataType فقط فروشگاه ابرداده. به عنوان مثال, DataTypeUInt8 هیچ چیزی را ذخیره نمی کند (به جز ویپر) و DataTypeFixedString فروشگاه ها فقط N (اندازه رشته های ثابت).

IDataType دارای روش های کمکی برای فرمت های داده های مختلف. نمونه روش برای مرتب کردن یک مقدار با امکان نقل قول, برای مرتب کردن یک مقدار برای جانسون, و برای مرتب کردن یک مقدار به عنوان بخشی از فرمت میلی لیتر. هیچ مکاتبات مستقیم به فرمت های داده وجود دارد. برای مثال فرمت های داده های مختلف Pretty و TabSeparated می توانید همان استفاده کنید serializeTextEscaped روش کمکی از IDataType واسط.

بلوک

A Block یک ظرف است که نشان دهنده یک زیر مجموعه است (تکه) از یک جدول در حافظه. این فقط مجموعه ای از سه برابر است: (IColumn, IDataType, column name). در طول اجرای پرس و جو, داده ها توسط پردازش Blockاگر ما یک Block, ما داده (در IColumn هدف), ما باید اطلاعات در مورد نوع خود (به IDataType) که به ما می گوید که چگونه به مقابله با این ستون, و ما باید نام ستون. این می تواند یا نام ستون اصلی از جدول و یا برخی از نام مصنوعی اختصاص داده شده برای گرفتن نتایج موقت از محاسبات.

هنگامی که ما برخی از تابع محاسبه بیش از ستون در یک بلوک, ما اضافه کردن ستون دیگر با نتیجه خود را به بلوک, و ما ستون برای استدلال از تابع را لمس کنید چرا که عملیات تغییر ناپذیر هستند. بعد, ستون غیر ضروری را می توان از بلوک حذف, اما اصلاح نشده. مناسب برای از بین بردن اکسپرس مشترک است.

بلوک برای هر تکه پردازش داده ها ایجاد شده است. توجه داشته باشید که برای همان نوع از محاسبه, نام ستون و انواع یکسان باقی می ماند برای بلوک های مختلف, و تنها ستون تغییرات داده. بهتر است داده های بلوک را از هدر بلوک تقسیم کنید زیرا اندازه های بلوک کوچک دارای سربار بالایی از رشته های موقت برای کپی کردن نام های شکسته و ستون هستند.

بلوک جریان

جریان بلوک برای پردازش داده ها می باشد. ما با استفاده از جریان بلوک به خواندن داده ها از جایی انجام داده تحولات و یا نوشتن داده ها به جایی. IBlockInputStream دارد read روش به بهانه بلوک بعدی در حالی که در دسترس. IBlockOutputStream دارد write روش به فشار بلوک جایی.

جریان ها برای:

  1. خواندن و یا نوشتن به یک جدول. جدول فقط می گرداند یک جریان برای خواندن و یا نوشتن بلوک.
  2. اجرای فرمت های داده. مثلا, اگر شما می خواهید به خروجی داده ها به یک ترمینال در Pretty شما یک جریان خروجی بلوک ایجاد می کنید که بلوک ها را فشار می دهید و فرمت می کند.
  3. انجام تحولات داده ها. بیایید می گویند شما IBlockInputStream و می خواهید برای ایجاد یک جریان فیلتر شده است. شما ایجاد FilterBlockInputStream و با جریان خود را مقداردهی اولیه. سپس هنگامی که شما جلو و یک بلوک از FilterBlockInputStream, این نیش ترمزی میزند یک بلوک از جریان خود را, فیلتر, و گرداند بلوک فیلتر به شما. خطوط لوله اجرای پرس و جو در این راه نشان داده شده است.

تحولات پیچیده تر وجود دارد. مثلا, زمانی که شما از جلو AggregatingBlockInputStream تمام داده ها را از منبع خود می خواند و جمع می کند و سپس جریان داده های جمع شده را برای شما باز می گرداند. مثال دیگر: UnionBlockInputStream می پذیرد بسیاری از منابع ورودی در سازنده و همچنین تعدادی از موضوعات. این راه اندازی موضوعات متعدد و بار خوانده شده از منابع مختلف به صورت موازی.

بلوک جریان استفاده از “pull” رویکرد به کنترل جریان: هنگامی که شما یک بلوک جلو و از جریان اول, در نتیجه می کشد بلوک های مورد نیاز از جریان تو در تو, و کل خط لوله اعدام کار خواهد کرد. نه “pull” نه “push” بهترین راه حل است زیرا جریان کنترل ضمنی است و محدودیت اجرای ویژگی های مختلف مانند اجرای همزمان چندین نمایش داده شد (ادغام بسیاری از خطوط لوله با هم). این محدودیت می تواند با کروتین ها و یا فقط در حال اجرا موضوعات اضافی که برای یکدیگر صبر غلبه بر. ما ممکن است امکانات بیشتری داشته باشیم اگر جریان کنترل را صریح کنیم: اگر منطق را برای عبور داده ها از یک واحد محاسبه به خارج دیگری از این واحدهای محاسبه قرار دهیم. خواندن این مقاله برای افکار بیشتر.

ما باید توجه داشته باشید که خط لوله اجرای پرس و جو ایجاد داده های موقت در هر مرحله. ما سعی می کنیم برای حفظ اندازه بلوک به اندازه کافی کوچک به طوری که داده های موقت متناسب در کش پردازنده. با این فرض, نوشتن و خواندن داده های موقت تقریبا رایگان در مقایسه با محاسبات دیگر است. ما می توانیم یک جایگزین در نظر, است که به فیوز بسیاری از عملیات در خط لوله با هم. این می تواند خط لوله به عنوان کوتاه که ممکن است و حذف بسیاری از اطلاعات موقت, که می تواند یک مزیت, اما همچنین دارای اشکالاتی. مثلا, یک خط لوله تقسیم باعث می شود به راحتی پیاده سازی ذخیره داده متوسط, سرقت اطلاعات متوسط از نمایش داده شد مشابه در حال اجرا در همان زمان, و ادغام خطوط لوله برای نمایش داده شد مشابه.

فرشها

فرمت های داده ها با جریان بلوک اجرا شده است. وجود دارد “presentational” فرمت تنها مناسب برای خروجی داده ها به مشتری مانند Pretty قالب, فراهم می کند که تنها IBlockOutputStream. و فرمت های ورودی / خروجی مانند TabSeparated یا JSONEachRow.

همچنین جریان ردیف وجود دارد: IRowInputStream و IRowOutputStream. اجازه می دهد شما را به جلو و/فشار داده های ردیف های فردی, نه با بلوک. و فقط برای ساده سازی اجرای فرمت های ردیف گرا نیاز دارند. لفافه BlockInputStreamFromRowInputStream و BlockOutputStreamFromRowOutputStream به شما اجازه تبدیل جریان ردیف گرا به جریان بلوک گرا به طور منظم.

I/O

برای ورودی بایت گرا / خروجی, وجود دارد ReadBuffer و WriteBuffer کلاس های انتزاعی. به جای ج++استفاده می شود iostreamنگران نباشید: هر پروژه سی++ بالغ با استفاده از چیزی غیر از iostreamبه دلایل خوب.

ReadBuffer و WriteBuffer فقط یک بافر پیوسته و مکان نما با اشاره به موقعیت در بافر که. پیاده سازی ممکن است خود و یا حافظه برای بافر خود را ندارد. یک روش مجازی برای پر کردن بافر با داده های زیر وجود دارد (برای ReadBuffer) و یا به خیط و پیت کردن بافر جایی (برای WriteBuffer). روش های مجازی به ندرت نامیده می شود.

پیاده سازی از ReadBuffer/WriteBuffer برای کار با فایل ها و توصیفگر فایل ها و سوکت های شبکه برای اجرای فشرده سازی استفاده می شود (CompressedWriteBuffer is initialized with another WriteBuffer and performs compression before writing data to it), and for other purposes the names ConcatReadBuffer, LimitReadBuffer و HashingWriteBuffer صحبت برای خود.

خواندن / نویسنده تنها با بایت برخورد. توابع از وجود دارد ReadHelpers و WriteHelpers فایل های هدر برای کمک به قالب بندی ورودی / خروجی. برای مثال یاران به نوشتن یک شماره در قالب دهدهی وجود دارد.

بیایید نگاه کنیم که چه اتفاقی می افتد زمانی که می خواهید نتیجه را بنویسید JSON قالب به چاق و چله. شما باید یک نتیجه مجموعه ای از ذهن می شود IBlockInputStream. شما ایجاد WriteBufferFromFileDescriptor(STDOUT_FILENO) برای نوشتن بایت به چاق و چله. شما ایجاد JSONRowOutputStream, مقداردهی اولیه با که WriteBuffer برای نوشتن ردیف در JSON به چاق و چله. شما ایجاد BlockOutputStreamFromRowOutputStream در بالای این, برای نشان دادن به عنوان IBlockOutputStream. سپس با شما تماس copyData برای انتقال داده ها از IBlockInputStream به IBlockOutputStream, و همه چیز کار می کند. داخلی, JSONRowOutputStream خواهد شمارشگر های مختلف جانسون ارسال و پاسخ IDataType::serializeTextJSON روش با اشاره به IColumn و شماره ردیف به عنوان استدلال. در نتیجه, IDataType::serializeTextJSON یک روش از پاسخ WriteHelpers.h: به عنوان مثال, writeText برای انواع عددی و writeJSONString برای DataTypeString.

جداول

این IStorage رابط نشان دهنده جداول. پیاده سازی های مختلف که رابط موتورهای جدول متفاوت است. مثالها عبارتند از StorageMergeTree, StorageMemory و به همین ترتیب. نمونه هایی از این کلاس ها فقط جداول.

کلید IStorage روش read و write. همچنین وجود دارد alter, rename, drop و به همین ترتیب. این read روش استدلال های زیر را می پذیرد: مجموعه ای از ستون ها برای خواندن از یک جدول AST پرس و جو را در نظر بگیرید, و تعداد مورد نظر از جریان به بازگشت. این گرداند یک یا چند IBlockInputStream اشیا و اطلاعات در مورد مرحله پردازش داده ها که در داخل یک موتور جدول در طول اجرای پرس و جو تکمیل شد.

در بیشتر موارد, روش خواندن تنها برای خواندن ستون مشخص شده از یک جدول است, نه برای هر پردازش داده ها بیشتر. تمام پردازش داده های بیشتر توسط مترجم پرس و جو انجام می شود و خارج از وظیفه است IStorage.

اما استثنا قابل توجه وجود دارد:

  • پرس و جو اس تی به تصویب رسید read روش, و موتور جدول می توانید استفاده کنید به استفاده از شاخص و به خواندن اطلاعات کمتر از یک جدول.
  • گاهی موتور جدول می تواند داده های خود را به یک مرحله خاص پردازش. به عنوان مثال, StorageDistributed می توانید یک پرس و جو به سرور از راه دور ارسال, از او بخواهید برای پردازش داده ها به مرحله ای که داده ها را از سرور های مختلف از راه دور را می توان با هم ادغام شدند, و بازگشت که داده های پیش پردازش. مترجم پرس و جو سپس پس از اتمام پردازش داده ها.

جدول read روش می تواند چندین بازگشت IBlockInputStream اشیا اجازه می دهد تا پردازش داده های موازی. این جریان ورودی بلوک های متعدد می توانید از یک جدول به صورت موازی به عنوان خوانده شده. سپس شما می توانید این جریان با تحولات مختلف قرار دادن (مانند ارزیابی بیان و یا فیلتر) است که می تواند به طور مستقل محاسبه و ایجاد یک UnionBlockInputStream برای خواندن از جریانهای چندگانه به صورت موازی.

همچنین وجود دارد TableFunctionاین توابع که بازگشت موقت هستند IStorage شی برای استفاده در FROM بند یک پرس و جو.

برای دریافت یک ایده سریع از نحوه پیاده سازی موتور جدول خود را در چیزی ساده مانند نگاه StorageMemory یا StorageTinyLog.

به عنوان نتیجه read روش, IStorage بازگشت QueryProcessingStage information about what parts of the query were already calculated inside storage.

Parsers

تجزیه کننده تبار بازگشتی دست نوشته تجزیه کننده تجزیه پرس و جو تجزیه. به عنوان مثال, ParserSelectQuery فقط به صورت بازگشتی تماس تجزیه کننده زمینه ای برای بخش های مختلف از پرس و جو. تجزیه کننده ایجاد یک AST. این AST توسط گره هایی که نمونه هایی از IAST.

ژنراتور تجزیه کننده به دلایل تاریخی استفاده نمی شود.

مترجمین

مترجمین برای ایجاد خط لوله اجرای پرس و جو از AST. می مفسران ساده وجود دارد, مانند InterpreterExistsQuery و InterpreterDropQuery یا پیچیده تر InterpreterSelectQuery. خط لوله اجرای پرس و جو ترکیبی از ورودی بلوک یا جریان خروجی است. برای مثال نتیجه تفسیر SELECT پرس و جو است IBlockInputStream برای خواندن نتیجه مجموعه ای از; نتیجه پرس و جو درج است IBlockOutputStream برای نوشتن داده ها برای درج به, و در نتیجه تفسیر INSERT SELECT پرس و جو است IBlockInputStream که نتیجه خالی را برمی گرداند مجموعه ای در خواندن برای اولین بار, اما نسخه داده ها از SELECT به INSERT در همان زمان.

InterpreterSelectQuery استفاده ExpressionAnalyzer و ExpressionActions ماشین برای تجزیه و تحلیل پرس و جو و تحولات. این جایی است که اکثر بهینه سازی پرس و جو مبتنی بر قانون انجام می شود. ExpressionAnalyzer کاملا کثیف است و باید بازنویسی شود: تحولات پرس و جو های مختلف و بهینه سازی باید استخراج به کلاس های جداگانه اجازه می دهد تا تحولات مدولار و یا پرس و جو.

توابع

توابع عادی و توابع کل وجود دارد. برای توابع کل, بخش بعدی را ببینید.

Ordinary functions don't change the number of rows they work as if they are processing each row independently. In fact, functions are not called for individual rows, but for Block'ثانیه از داده ها برای پیاده سازی اجرای پرس و جو بردار.

برخی از توابع متفرقه مانند وجود دارد blockSize, رفع موانع و خرابی اجرا, که بهره برداری از پردازش بلوک و نقض استقلال ردیف.

تاتر تایپ قوی, بنابراین هیچ تبدیل نوع ضمنی وجود دارد. اگر یک تابع یک ترکیب خاص از انواع پشتیبانی نمی کند, این می اندازد یک استثنا. اما توابع می توانند کار کنند (غیرمنتظره) برای بسیاری از ترکیبات مختلف از انواع. برای مثال plus تابع (برای پیاده سازی + اپراتور) برای هر ترکیبی از انواع عددی کار می کند: UInt8 + Float32, UInt16 + Int8 و به همین ترتیب. همچنین, برخی از توابع مختلف می توانید هر تعداد از استدلال قبول, مانند concat تابع.

اجرای یک تابع ممکن است کمی ناخوشایند به دلیل یک تابع به صراحت اعزام انواع داده ها پشتیبانی و پشتیبانی IColumns. برای مثال plus تابع دارای کد تولید شده توسط نمونه از یک ج++ قالب برای هر ترکیبی از انواع عددی, و استدلال چپ و راست ثابت یا غیر ثابت.

این یک محل عالی برای اجرای تولید کد زمان اجرا برای جلوگیری از نفخ کد الگو است. همچنین, این امکان را برای اضافه کردن توابع ذوب مانند ذوب ضرب-اضافه کردن و یا به مقایسه های متعدد در یک تکرار حلقه.

با توجه به اجرای پرس و جو بردار, توابع کوتاه دور نیست. مثلا, اگر شما ارسال WHERE f(x) AND g(y), هر دو طرف محاسبه می شود, حتی برای ردیف, وقتی که f(x) صفر است (به جز زمانی که f(x) بیان ثابت صفر است). اما اگر انتخاب از f(x) شرایط بالا و محاسبه است f(x) بسیار ارزان تر از g(y) بهتر است محاسبات چند گذر را اجرا کنید. این برای اولین بار محاسبه f(x) سپس ستون ها را با نتیجه فیلتر کنید و سپس محاسبه کنید g(y) فقط برای کوچکتر, تکه های فیلتر شده از داده ها.

توابع مجموع

توابع مجموع توابع نفرت انگیز هستند. جمع ارزش به برخی از دولت منتقل می شود و به شما اجازه دریافت نتایج از دولت. با مدیریت IAggregateFunction واسط. ایالات می تواند نسبتا ساده (دولت برای AggregateFunctionCount تنها یک UInt64 ارزش) و یا کاملا پیچیده (دولت از AggregateFunctionUniqCombined ترکیبی از یک مجموعه خطی است, یک جدول هش, و یک HyperLogLog ساختار داده احتمالاتی).

ایالات در اختصاص داده Arena (یک استخر حافظه) برای مقابله با کشورهای مختلف در حالی که اجرای یک کارتیت بالا GROUP BY پرس و جو. ایالات می تواند یک سازنده غیر بدیهی و مخرب دارند: مثلا, کشورهای تجمع پیچیده می توانید حافظه اضافی خود اختصاص. این نیاز به توجه به ایجاد و از بین بردن ایالات و به درستی عبور مالکیت و تخریب سفارش خود را.

تجمع متحده می تواند سرهمی و deserialized به تصویب بیش از این شبکه در توزیع پرس و جو اعدام و یا ارسال آنها را بر روی دیسک که در آن وجود دارد به اندازه کافی نمی رم. حتی می توانند در یک جدول با DataTypeAggregateFunction اجازه می دهد تا تجمع افزایشی از داده ها.

فرمت داده سریال برای عملکرد کل ایالات در حال حاضر نسخه نیست. این خوب است اگر کشورهای کل تنها به طور موقت ذخیره می شود. اما ما AggregatingMergeTree جدول موتور به صورت افزایشی تجمع و مردم در حال حاضر استفاده از آن در تولید. این است دلیل که چرا سازگاری مورد نیاز است زمانی که تغییر سریال با فرمت برای هر aggregate function در آینده است.

کارگزار

سرور پیاده سازی چندین رابط های مختلف:

  • رابط قام برای هر مشتریان خارجی.
  • یک رابط واحد کنترل گیربکس اتوماتیک برای مشتری خانه رعیتی بومی و برای ارتباط متقابل سرور در طول اجرای پرس و جو توزیع شده است.
  • رابط کاربری برای انتقال داده ها برای تکرار.

داخلی, این فقط یک سرور چند رشته ای بدوی بدون کروتین یا الیاف است. از زمانی که سرور طراحی نشده است برای پردازش نرخ بالای ساده نمایش داده شد اما برای پردازش نسبتا پایین نرخ پیچیده نمایش داده شد هر یک می تواند روند مقدار زیادی از داده ها برای تجزیه و تحلیل ترافیک.

سرور مقدار دهی اولیه Context کلاس با محیط لازم برای اجرای پرس و جو: لیستی از پایگاه داده های موجود, کاربران و حقوق دسترسی, تنظیمات, خوشه, لیست فرایند, ورود به سیستم پرس و جو, و غیره. مفسران استفاده از این محیط.

ما سازگاری کامل رو به عقب و رو به جلو را برای پروتکل سرور تی سی پی حفظ می کنیم: مشتریان قدیمی می توانند با سرورهای جدید صحبت کنند و مشتریان جدید می توانند با سرورهای قدیمی صحبت کنند. اما ما نمی خواهیم تا ابد حفظ کنیم و پس از حدود یک سال پشتیبانی از نسخه های قدیمی را از بین می بریم.

!!! note "یادداشت" برای اکثر برنامه های کاربردی خارجی, توصیه می کنیم با استفاده از رابط اچ تی پی به دلیل ساده و ساده برای استفاده است. پروتکل تی سی پی به شدت با ساختارهای داده داخلی ارتباط دارد: از فرمت داخلی برای عبور بلوک های داده استفاده می کند و از فریم های سفارشی برای داده های فشرده استفاده می کند. ما یک کتابخانه سی که برای پروتکل منتشر نشده است چرا که نیاز به ارتباط بسیاری از کدهای کلیکهاوس, که عملی نیست.

اجرای پرس و جو توزیع شده

سرور در راه اندازی خوشه عمدتا مستقل هستند. شما می توانید یک Distributed جدول در یک یا تمام سرور در یک خوشه. این Distributed table does not store data itself it only provides a “view” به تمام جداول محلی در گره های متعدد از یک خوشه. هنگامی که شما از یک انتخاب Distributed جدول, بازنویسی است که پرس و جو, را گره از راه دور با توجه به بار تنظیمات متعادل, و پرس و جو را به او می فرستد. این Distributed درخواست جدول سرور از راه دور برای پردازش یک پرس و جو فقط تا مرحله ای که نتایج متوسط از سرور های مختلف را می توان با هم ادغام شدند. سپس نتایج متوسط را دریافت می کند و ادغام می کند. جدول توزیع تلاش می کند برای توزیع کار به همان اندازه که ممکن است به سرور از راه دور می کند و داده های متوسط بسیار بیش از شبکه ارسال کنید.

همه چیز پیچیده تر می شود زمانی که شما زیر کشتیها در و یا پیوستن به بند, و هر یک از استفاده از یک Distributed جدول ما استراتژی های مختلف برای اجرای این نمایش داده شد.

هیچ برنامه پرس و جو جهانی برای اجرای پرس و جو توزیع وجود دارد. هر گره دارای برنامه پرس و جو محلی خود را برای بخشی خود را از کار. ما فقط ساده یک پاس اجرای پرس و جو توزیع شده: ما ارسال نمایش داده شد برای گره های از راه دور و سپس ادغام نتایج. اما این امکان پذیر نیست برای نمایش داده شد پیچیده با بالا کار افتادگی گروه بورس و یا با مقدار زیادی از داده های موقت برای پیوستن به. در چنین مواردی ما نیاز به “reshuffle” داده ها بین سرور, که نیاز به هماهنگی اضافی. کلیک هاوس از این نوع اجرای پرس و جو پشتیبانی نمی کند و ما باید روش کار کنیم.

ادغام درخت

MergeTree یک خانواده از موتورهای ذخیره سازی است که پشتیبانی از نمایه سازی توسط کلید اصلی است. کلید اصلی می تواند یک تاپل دلخواه از ستون ها و یا عبارات. داده ها در یک MergeTree جدول در ذخیره می شود “parts”. هر بخش ذخیره داده ها در جهت کلید اولیه, بنابراین داده ها از لحاظ واژگان توسط تاپل کلید اولیه دستور داد. تمام ستون های جدول به صورت جداگانه ذخیره می شوند column.bin فایل ها در این بخش. فایل ها از بلوک های فشرده تشکیل شده است. هر بلوک است که معمولا از 64 کیلوبایت به 1 مگابایت از داده های غیر فشرده, بسته به اندازه مقدار متوسط. بلوک از مقادیر ستون بعد از دیگری قرار داده شده به طور یکنواخت تشکیل شده است. مقادیر ستون در همان جهت برای هر ستون هستند (کلید اصلی سفارش را تعریف می کند), تا زمانی که شما توسط بسیاری از ستون تکرار, شما ارزش برای ردیف مربوطه.

کلید اصلی خود است “sparse”. این کار هر سطر رسیدگی نمی, اما تنها برخی از محدوده داده. جدا primary.idx فایل دارای ارزش کلید اصلی برای هر سطر نفر که نفر نامیده می شود index_granularity (معمولا, نفر = 8192). همچنین, برای هر ستون, ما داریم column.mrk پروندهها با “marks,” که ناراحتی به هر سطر نفر هفتم در فایل داده ها. هر علامت یک جفت است: افست در فایل به ابتدای بلوک فشرده و افست در بلوک فشرده به ابتدای داده ها. معمولا, بلوک های فشرده توسط علامت تراز وسط قرار دارد, و افست در بلوک فشرده صفر است. داده ها برای primary.idx همیشه در حافظه ساکن, و داده ها را برای column.mrk فایل های ذخیره شده است.

هنگامی که ما می رویم به خواندن چیزی از یک شرکت در MergeTree ما نگاه می کنیم primary.idx داده ها و تعیین محل محدوده است که می تواند حاوی اطلاعات درخواست شده و سپس نگاه column.mrk داده ها و محاسبه شیپور خاموشی برای جایی که شروع به خواندن این محدوده. به دلیل نرمی, اطلاعات اضافی ممکن است به عنوان خوانده شده. تاتر مناسب برای یک بار بالا از نمایش داده شد نقطه ساده نیست, چرا که کل محدوده با index_granularity ردیف باید برای هر کلید به عنوان خوانده شده, و کل بلوک فشرده باید برای هر ستون از حالت فشرده خارج. ما جرقه شاخص ساخته شده چرا که ما باید قادر به حفظ تریلیون ردیف در هر سرور بدون مصرف حافظه قابل توجه برای شاخص باشد. همچنین, به دلیل کلید اصلی پراکنده است, منحصر به فرد نیست: این می تواند وجود کلید در جدول در زمان درج بررسی نمی. شما می توانید ردیف های بسیاری را با همان کلید در یک جدول داشته باشید.

هنگامی که شما INSERT یک دسته از داده ها به MergeTree, که دسته مرتب شده بر اساس کلید اصلی سفارش و به شکل یک بخش جدید. موضوعات پس زمینه وجود دارد که به صورت دوره ای برخی از قطعات را انتخاب می کنند و به یک بخش مرتب شده اند تا تعداد قطعات نسبتا کم باشد. به همین دلیل است که نامیده می شود MergeTree. البته ادغام منجر به “write amplification”. تمام قطعات تغییر ناپذیر هستند: تنها ایجاد و حذف, اما اصلاح نشده. هنگامی که انتخاب اجرا شده است, دارای یک تصویر لحظهای از جدول (مجموعه ای از قطعات). پس از ادغام, ما همچنین قطعات قدیمی برای برخی از زمان به بهبود پس از شکست ساده تر نگه, بنابراین اگر ما می بینیم که برخی از بخش ادغام شده است که احتمالا شکسته, ما می توانیم با قطعات منبع خود را جایگزین.

MergeTree یک درخت ل اس ام نیست زیرا حاوی نیست “memtable” و “log”: inserted data is written directly to the filesystem. This makes it suitable only to INSERT data in batches, not by individual row and not very frequently about once per second is ok, but a thousand times a second is not. We did it this way for simplicity's sake, and because we are already inserting data in batches in our applications.

جداول ادغام تنها می توانید یک دارند (اولیه) شاخص: هیچ شاخص ثانویه وجود ندارد. این امر می تواند خوب اجازه می دهد تا بازنمایی فیزیکی متعدد تحت یک جدول منطقی, مثلا, برای ذخیره داده ها در بیش از یک نظم فیزیکی و یا حتی اجازه می دهد تا بازنمایی با داده های از پیش جمع همراه با داده های اصلی.

موتورهای ادغام است که کار اضافی در طول پس زمینه ادغام انجام می دهند وجود دارد. مثالها عبارتند از CollapsingMergeTree و AggregatingMergeTree. این می تواند به عنوان پشتیبانی ویژه ای برای به روز رسانی درمان می شود. به خاطر داشته باشید که این به روز رسانی واقعی نیست چرا که کاربران معمولا هیچ کنترلی بر زمان هنگامی که پس زمینه ادغام اجرا می شوند, و داده ها در یک MergeTree جدول تقریبا همیشه در بیش از یک بخش ذخیره می شود, نه در فرم به طور کامل با هم ادغام شدند.

تکرار

تکرار در کلیک خانه را می توان بر اساس هر جدول پیکربندی شده است. شما می توانید برخی از تکرار و برخی از جداول غیر تکرار بر روی همان سرور. شما همچنین می تواند جداول تکرار در راه های مختلف, مانند یک جدول با تکرار دو عامل و دیگری با سه عامل.

تکرار در اجرا ReplicatedMergeTree موتور ذخیره سازی. مسیر در ZooKeeper به عنوان یک پارامتر برای موتور ذخیره سازی مشخص شده است. تمام جداول با همان مسیر در ZooKeeper تبدیل کپی از یکدیگر: همگام سازی داده های خود و حفظ ثبات. کپی می تواند اضافه شود و به صورت پویا به سادگی با ایجاد و یا حذف یک جدول حذف شده است.

تکرار با استفاده از یک طرح چند استاد ناهمزمان. شما می توانید داده ها را به هر ماکت است که یک جلسه با وارد ZooKeeper, و داده ها به تمام کپی های دیگر غیر همزمان تکرار. چون کلیک هاوس به روز رسانی را پشتیبانی نمی کند, تکرار بدون درگیری است. همانطور که هیچ اذعان حد نصاب درج وجود دارد, داده فقط قرار داده ممکن است از دست داده اگر یک گره نتواند.

فراداده برای تکرار در باغ وحش ذخیره می شود. ورود به سیستم تکرار است که لیست چه اقداماتی را انجام دهید وجود دارد. اقدامات عبارتند از: دریافت بخشی; ادغام قطعات; رها کردن یک پارتیشن, و غیره. هر ماکت کپی ورود تکرار به صف خود و سپس اجرا اقدامات از صف. برای مثال در درج “get the part” عمل در ورود به سیستم ایجاد, و هر دانلود ماکت که بخشی. ادغام بین کپی هماهنگ برای دریافت بایت - نتایج یکسان. تمام قطعات در همان راه در تمام کپی با هم ادغام شدند. این است که با انتخاب یک ماکت به عنوان رهبر دست, و این ماکت شروع ادغام و می نویسد “merge parts” عملیات به ورود به سیستم.

تکرار فیزیکی است: تنها قطعات فشرده بین گره منتقل, نمایش داده شد نیست. ادغام در هر ماکت پردازش به طور مستقل در اکثر موارد به کاهش هزینه های شبکه با اجتناب از تقویت شبکه. قطعات با هم ادغام شدند بزرگ بر روی شبکه تنها در موارد تاخیر تکرار قابل توجهی ارسال.

بعلاوه, هر ماکت ذخیره دولت خود را در باغ وحش به عنوان مجموعه ای از قطعات و چک سام خود. هنگامی که دولت در فایل سیستم محلی واگرا از دولت مرجع در باغ وحش, ماکت بازیابی سازگاری خود را با دانلود قطعات گم شده و شکسته از دیگر کپی. هنگامی که برخی از داده های غیر منتظره و یا شکسته در فایل سیستم محلی وجود دارد, خانه را حذف کنید, اما حرکت می کند به یک دایرکتوری جداگانه و فراموش.

!!! note "یادداشت" خوشه محل کلیک متشکل از خرده ریز مستقل, و هر سفال شامل کپی. خوشه است الاستیک نیست, بنابراین پس از اضافه کردن یک سفال جدید, داده ها بین خرده ریز به طور خودکار توازن نیست. بجای, بار خوشه قرار است تنظیم شود ناهموار. این پیاده سازی به شما کنترل بیشتری می دهد و برای خوشه های نسبتا کوچک مانند ده ها گره مناسب است. اما برای خوشه با صدها گره که ما با استفاده از در تولید, این رویکرد یک نقطه ضعف قابل توجهی می شود. ما باید یک موتور جدول است که دهانه در سراسر خوشه با مناطق به صورت پویا تکرار است که می تواند تقسیم و متعادل کننده شده بین خوشه به طور خودکار پیاده سازی.

{## مقاله اصلی ##}