در این قسمت قصد داریم با index ها و خصوصیات آنها در Elasticsearch آشنا شویم. در قسمتهای قبلی دیدیم که برای ایجاد index الزامی ندارد حتما تنظیمات و ساختار آن را تعیین کنیم و کافیست ضمن index کردن document، نامی برای index مشخص کنیم تا به طور خودکار index مورد نظر ساخته شود.
اما این روش کنترل ما در تنظیمات index را محدود میکند و برای تغییر برخی از تنظیمات index شاید مجبور شویم در آینده دادهها را به یک index جدید که طبق نیازمندی ما ایجاد شده باشد، منتقل کنیم و یا تغییرات گستردهای در دادهها ایجاد کنیم. به عنوان مثال وقتی Elasticsearch به صورت خودکار datatype فیلدها را مشخص کند، یک datatype از نوع keyword و یک datatype از نوع text برای هر فیلد متنی به صورت پیشفرض درنظر میگیرد (با انواع datatype ها و تفاوت های آنها در قسمت بعدی آشنا خواهیم شد). این کار باعث میشود حجم بیشتری داده به ازای هر فیلد متنی در حافظه ذخیره شود در صورتی که شاید این datatype ها برای خیلی از فیلدها کاربردی نباشد و صرفا فضای بیشتری را اشغال کند. بنابراین بهتر است از ابتدا index و ساختار آن را به شکلی دقیقتر و آگاهانه ایجاد کنیم.
برای ایجاد یک index، میتوان از API مخصوص آن استفاده کرد. این API با متود PUT فراخوانی میشود:
PUT /<index-name>
{
}
که در قسمت <index-name> نام دلخواهی برای index تعیین میشود. اما استفاده از این API به این سادگی و بدون هیچ پارامتری، فرقی با همان کاری که Elasticsearch به طور خودکار برای ایجاد index انجام میدهد ندارد! در واقع هر index در Elasticsearch از ماژولهایی تشکیل شده است که هنگام ایجاد آن میتوان تنظیمات این ماژولها را مشخص کرد.
تنظیمات index در دو دستهی static و dynamic تقسیم میشوند. تنظیمات static فقط در زمان ایجاد index و یا در حالتی که index بسته(close) باشد (حالت close جزو metadata یک index است که در این حالت هیچ عملیاتی روی index قابل اجرا نیست) قابل تنظیم هستند و تنظیمات dynamic را میتوان هر زمان (حتی پس از ایجاد index) توسط API بروزرسانی تنظیمات، تغییر داد.
ابتدا با مهمترین تنظیمات index که زیرمجموعهی ماژول خاصی نیستند، آشنا شویم:
index.number_of_shards:این تنظیم static بوده و تعداد shard های index را مشخص میکند. پیشفرض مقدار آن 1 میباشد. به طور کلی توصیه میشود از تعداد زیادی shard با حجم کم داده، اجتناب شود و تا زمانی که حجم دادههای index تا حدود 20 گیگابایت نرسیده است، تعداد 1 shard کفایت میکند.
index.number_of_replicas: این تنظیم dynamic است و تعداد نسخههای replica را تعیین میکند. مقدار پیشفرض آن 1 میباشد و در صورتی این تنظیم کارایی دارد که بیش از یک node در cluster موجود باشد! برای مثال اگر تعداد primary shard برابر با 3 باشد و مقدار این تنظیم 2 تعیین شود، برای هر یک از primary shard ها، 2 نسخهی replica خواهیم داشت (در مجموع تعداد replica shard ها برابر 6 میشود). هریک از این replica shard ها به گونهای در cluster توزیع میشوند که هیچ primary shard همراه با replica shard متناظرش در یک node قرار نگیرند.
تنظیمات زیر برای کنترل عملیاتهای قابل اجرا در یک index قابل استفاده بوده و همگی dynamic میباشند:
index.blocks.read_only: مقدار true برای این تنظیم، index را در حالت read-only قرار میدهد (اجازهی نوشتن و تغییر metadata را نمیدهد) و مقدار false اجازهی عملیات نوشتن و تغییر metadata را برای index فعال میکند. پیشفرض مقدار false دارد.
index.blocks.read: مقدار true عملیات خواندن در index را غیرفعال میکند و false اجازهی خواندن را فعال میکند. عملیات خواندن شامل search API و get API میشود. مقدار پیشفرض false است.
index.blocks.write: مقدار true عملیات نوشتن در index را غیرفعال میکند و false اجازهی نوشتن را فعال میکند. مقدار پیشفرض false است.
index.blocks.metadata: هرگونه اطلاعاتی غیر از دادههای document های یک index را metadata آن index میگوییم. مقدار true عملیات خواندن و نوشتن metadata در index را غیرفعال میکند و مقدار false اجازه خواندن و نوشتن metadata را فعال میکند. مقدار پیشفرض false است.
در ادامه با برخی ماژولهای مهم index آشنا میشویم:
- Analysis: در این ماژول تنظیمات مربوط به تعریف analyzer ها و اجزای آنها تعیین میشود. در واقع هر index میتواند analyzer های خاص خود را برای تجزیه دادههایش داشته باشد. در خصوص analyzer در فصلهای آینده به طور مفصل صحبت خواهیم کرد.
- Mapper (Mapping): ماژول Mapper که با عنوان Mapping در بدنهی تنظیمات index ظاهر میشود، شامل تنظیمات مربوط به فیلدهای دادهای، datatype آنها، نوع analyzer آنها و ... میشود. این تنظیم مشابه Schema در پایگاه دادهی رابطهای عمل میکند. در قسمت بعدی در خصوص نحوهی کار با Mapping صحبت خواهیم کرد.
- Shard allocation: این ماژول تنظیمات نحوهی تخصیص shard های index در node ها را کنترل میکند. تنظیمات این بخش زمانی کاربردی است که بیش از یک node در cluster استفاده شود و بخواهیم تعیین کنیم دادههای یک index بنا به نیازمندیهای خاصی، در یک node با ویژگی خاص قرار گیرند. برای مثال اگر حجم زیادی از داده را در node هایی با تنظیمات سختافزاری مختلف ذخیره کرده باشیم و بخواهیم دادههای قدیمیتر به دلیل نرخ پایینتر دسترسی، در node هایی با سختافزار ضعیفتر نگهداری شده و دادههای جدیدتر به دلیل نرخ بالای خواندن و نوشتن، در node هایی با سختافزاری قویتر نگهداری شوند.
علاوه بر ماژولهای بالا، ماژولهای دیگری نیز وجود دارد که بیشتر در مباحث تخصصیتر و پیشرفته مورد استفاده هستند، مانند ماژولهای Similarity و Merge که در ابتدای کار با Elasticsearchنیازی به درگیر بودن با این ماژولها نمیباشد.
بسیار خوب برگردیم به API ایجاد index که در ابتدای این قسمت در مورد آن صحبت کردیم. در بدنهی این API میتوان تنظیمات ماژولهای index را از طریق کلیدهای settings و mappings به صورت زیر تعیین کرد:
PUT /<index-name>
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"field1": { "type": "text" }
}
}
}
کلید mappings مربوط به تنظیمات ماژول Mapper و کلید settings دربردارندهی سایر تنظیمات index میباشد. در کلید settings برای تنظیمات مربوط به یک ماژول ابتدا نام کلید مربوط به آن ماژول استفاده میشود برای مثال برای تعیین تنظیمات analysis مطابق ساختار زیر عمل میکنیم:
PUT /<index-name>
{
"settings": {
"analysis": {
…
}
}
}
و برای تنظیماتی که زیرمجموعهی ماژول خاصی نباشند، مستقیم در کلید settings تنظیم مورد نظر را استفاده میکنیم. مانند تنظیم number_of_shards در مثال زیر:
PUT /<index-name>
{
"settings": {
"number_of_shards": 3
}
}
در این قسمت با ساختار کلی مهمترین تنظیمات و ماژولهای index آشنا شدیم. در قسمت بعدی به جزییات کار با ماژول Mapper میپردازیم و در فصل آینده به ماژول Analysis خواهیم پرداخت.