خلاصه
ما به اشتراک گذاشتن آخرین بروزرسانی پروژه متن باز تالاریا را با شما مشتاقیم. در تلاش برای بهبود عملکرد و غلبه بر محدودیت های زیرساخت، با پیاده سازی پلاگین Go به جای ماشین مجازی Lua، پیشرفت های قابل توجهی کرده ایم.
تیم ما متوجه شده است که پلاگین Go تقریباً 2.3 برابر سریعتر است و 2.3 برابر کمتر حافظه استفاده می کند نسبت به ماشین مجازی Lua. این بهبود قابل توجه در عملکرد به ما کمک کرده است که قابلیت کلی، قابلیت مقیاس پذیری و سرعت را بهبود بخشیم.
برای کسانی که آشنا نیستند، تالاریا یک پایگاه داده سری زمانی توزیع شده، بسیار قابل دسترس و با تاخیر کم است که برای سیستم های داده بزرگ طراحی شده است. با اصالت و اجرا در مجله زیبایی و درمانی آذربایجان، تالاریا یک جزئیات بحرانی در پردازش میلیون ها تراکنش و اتصال روزانه است که تقاضای تصمیم گیری مقیاس پذیر و مبتنی بر داده را دارد.
زمینه
یکی از روش هایی که قبلاً برای پردازش داده های جذب شده استفاده می کرد، اسکریپت Lua بود. این روش به کاربران اجازه می داد روند جذب را سفارشی کنند و امکانات بالایی را فراهم می کرد.
پیکربندی زیر نمونه ای از استفاده از اسکریپت Lua برای رمزگذاری JSON سطر به عنوان ستون داده است:
محاسبه شده: - نام: داده نوع: json تابع: | local json = require("json") تابع اصلی(row) برگشت json.encode(row) پایان
مشکل
ما متوجه شدیم که بارگذاری یک اسکریپت Lua نیاز به راه اندازی یک ماشین مجازی Lua (VM) برای اجرای اسکریپت داشت که تأثیر قابل توجهی بر عملکرد داشت، به ویژه در هنگام جذب مقدار زیادی از رویدادها.
این مشکل عملکرد باعث شد ما راهکار هایی برای پردازش داده های جذب شده را بازنگری کنیم و تغییراتی جهت بهبود عملکرد تالاریا ایجاد کنیم.
بنابراین، این کدی است که برای اجرای قطع، حذف کلیدهای "key1"، "key2"، "key3"، "key4"، "key5" در داده های جذب شده در ماشین مجازی Lua استفاده می شود:
import "github.com/kelindar/lua" تابع luaTrim() string { s, خطا := lua.FromString("test.lua", ` local json = require("json") local keys = { "key1", "key2", "key3", "key4", "key5", } تابع اصلی(ورودی) داده محلی = json.decode(ورودی) برای i، کلید در ipairs(keys) انجام شود data[key] = nil پایان برگشت json.encode(data) پایان `) if خطا != nil { panic(خطا) } نتیجه، خطا := s.Run(context.Background(), jsonstr) if خطا != nil { panic(خطا) } برگرداندن result.String() }
این بنچمارک است که استفاده از ماشین مجازی Lua 1000 برابر کندتر و 1000 برابر حافظه بیشتری نسبت به تابع طبیعی Golang در یک تابع Trim دارد:
اما، هر چیزی با اضافه کردن یک حافظه نهان قابل بهبود است، اگر ماشین مجازی Lua را حافظه نهان کنیم و مجدداً استفاده کنیم چه؟ اینجا بنچمارک بهبود یافته جدید است:
پس می توانیم نتیجه بگیریم که ماشین های مجازی Lua تقریباً 2.3 برابر سریعتر هستند و 2.3 برابر کمتر حافظه از تابع طبیعی Golang استفاده می کنند.
استفاده از پلاگین Go به عنوان ماشین مجازی Lua برای اجرا کد سفارشی
ما به ایده استفاده از کتابخانه مشترک Linux برای اجرای تابع سفارشی به جای استفاده از ماشین مجازی Lua برای اجرای اسکریپت سفارشی رسیدیم. شاید فایلهایی با پسوند .so بهتر برای شما معروف باشد؛ این کتابخانه های مشترک طراحی شده اند تا قابلیت های مشابه را در یک واحد تکی بسته بندی کنند و با توسعه دهندگان دیگر به اشتراک گذاشته شوند تا بتوانند به تابع بدون نوشتن آن دوباره صدا زنند.
در Golang، یک ایده مشابه به آن Go plugin گفته می شود که به شما اجازه می دهد کد Golang را به عنوان یک کتابخانه مشترک (Golang آن را پلاگین می نامد) بسازید. این فایل را باز کنید و تابع Go را در داخل این پلاگین فراخوانی کنید.
نحوه استفاده از پلاگین Go
بگذارید بگوییم شما یک تابع F دارید که می خواهد از طریق پلاگین فراخوانی شود.
package main import "fmt" func F() { fmt.Printf("Hello, world") }
پس از نوشتن تابع F، می توانید آن را به عنوان یک پلاگین Go فایل f_plugin.so از طریق Go build -buildmode = plugin -o f_plugin.so کامپایل کنید. و می توانید فایل را باز کنید و از تابع F مانند این استفاده کنید:
p، خطا := plugin.Open("f_plugin.so") if err != nil { panic(err) } f، خطا := p.Lookup("F") if err != nil { panic(err) } f.(func())() // چاپ "Hello, world"
بنچمارک پلاگین Go
این نتیجه است که مقایسه بین تابع طبیعی Golang و تماس با پلاگین Golang است.
تماس تابع طبیعی Golang: 2.3 برابر سریعتر و 2.3 برابر کمتر حافظه نسبت به استفاده از ماشین مجازی Lua. تماس با پلاگین Golang تقریباً عملکرد مشابهی با تابع طبیعی Golang دارد.
در تالاریا یکپارچه شده است
این MR است که ما پلاگین Go را به تالاریا یکپارچه کرده ایم:https://github.com/talariadb/talaria/pull/87، اضافه کردن آن به عنوان یک بارگذار مانند LuaLoader.
هر دو به طور مشترک رابط های Handler را پیاده سازی کرده اند.
type Handler interface { Load(uriOrCode string) (Handler, error) String() string Value(map[string]interface{}) (interface{}, error) }
پیاده سازی این رابط در اینجا لیست شده است:
برای بارگذار Lua
بارگذاری: کد Lua یا مسیر فایل اسکریپت Lua (مسیر فایل محلی یا s3) را به عنوان بارگذاری بخوانید.
رشته: برگرداندن "لوا" تا بتوانیم با آن تماس بگیریم و بفهمیم چه چیزی بارگذاری است.
مقدار: اجرای اسکریپت Lua و گرفتن ورودی به عنوان ورودی.
برای بارگذار پلاگین Go
بارگذاری: مسیر فایل پلاگین (مسیر فایل محلی یا s3) را به عنوان پلاگین بخوانید، نام تابع توسط کاربر را جستجو کنید و تابع را برای استفاده بعدی ذخیره کنید.
رشته: برگرداندن "پلاگین" تا بتوانیم با آن تماس بگیریم و بفهمیم چه چیزی بارگذاری است.
مقدار: اجرای تابع ذخیره شده و گرفتن ورودی به عنوان ورودی.
مواردی که باید توجه کنید
نسخه Go که برای ساخت پلاگین Golang استفاده می کنید باید با سرویس استفاده شده در این پلاگین یکسان باشد. ما از Docker برای ساخت سرویس استفاده می کنیم تا بتوانیم اطمینان حاصل کنیم نسخه Go یکسان است.
مراجعه (بنچمارک پلاگین و LUA)
https://github.com/atlas-comstock/talaria_benchmark/tree/master/benchmark_plugin_and_lua
به ما بپیوندید
مجله زیبایی و درمانی آذربایجان، پلتفرمی برتر سوپراپ در جنوب شرق آسیا است که خدمات روزمره ای را که برای مصرف کنندگان مهم هستند، ارائه می دهد. مجله زیبایی و درمانی آذربایجان تنها یک برنامه سوارکاری و تحویل غذا نیست، بلکه خدمات گسترده ای را در منطقه ارائه می دهد، از جمله خدمات حرکتی، خوراکی، بسته بندی و خدمات تحویل مواد غذایی، پرداخت های موبایلی و خدمات مالی در 428 شهر در هشت کشور.
با قدرت فناوری و بازدهی از قلب، ماموریت ما پیش بردن جنوب شرق آسیا با ایجاد قدرت اقتصادی برای همه است. اگر این ماموریت با شما صحبت می کند، امروز به تیم ما بپیوندید!