کارگران پیگیر

این صفحه نحوه استفاده از کارگران مداوم، مزایا، الزامات و نحوه تأثیر کارگران بر سندباکس را پوشش می دهد.

یک کارگر مداوم یک فرآیند طولانی مدت است که توسط سرور Bazel آغاز شده است، که به عنوان یک بسته بندی در اطراف ابزار واقعی (معمولا یک کامپایلر) یا خود ابزار عمل می کند. برای بهره مندی از کارگران دائمی، ابزار باید از انجام دنباله ای از کامپایل ها پشتیبانی کند و wrapper باید بین API ابزار و فرمت درخواست/پاسخ توضیح داده شده در زیر ترجمه کند. همان کارگر ممکن است با و بدون پرچم --persistent_worker در همان بیلد فراخوانی شود و مسئول راه اندازی مناسب و صحبت کردن با ابزار و همچنین خاموش کردن کارگران در هنگام خروج است. هر نمونه کارگر به یک فهرست کاری جداگانه در زیر <outputBase>/bazel-workers اختصاص داده می شود (اما نه به کروت).

استفاده از کارگران دائمی یک استراتژی اجرایی است که سربار راه اندازی را کاهش می دهد، امکان کامپایل JIT بیشتری را فراهم می کند و به عنوان مثال درخت های نحو انتزاعی را در حافظه پنهان در اجرای عمل فعال می کند. این استراتژی با ارسال درخواست های متعدد به یک فرآیند طولانی مدت به این پیشرفت ها دست می یابد.

کارگران دائمی برای چندین زبان از جمله جاوا، اسکالا ، کاتلین و غیره پیاده‌سازی می‌شوند.

برنامه هایی که از زمان اجرا NodeJS استفاده می کنند می توانند از کتابخانه helper @bazel/worker برای پیاده سازی پروتکل کارگر استفاده کنند.

استفاده از کارگران مداوم

Bazel 0.27 و بالاتر هنگام اجرای بیلدها به طور پیش فرض از کارگران مداوم استفاده می کند، اگرچه اجرای از راه دور اولویت دارد. برای اقداماتی که از کارگران مداوم پشتیبانی نمی‌کنند، Bazel به شروع یک نمونه ابزار برای هر اقدام بازمی‌گردد. با تنظیم استراتژی worker برای یادگاری ابزار قابل اجرا، می توانید به صراحت ساخت خود را برای استفاده از کارگران پایدار تنظیم کنید. به عنوان بهترین روش، این مثال شامل مشخص کردن local به عنوان بازگشتی به استراتژی worker است:

bazel build //my:target --strategy=Javac=worker,local

استفاده از استراتژی کارگران به جای استراتژی محلی می تواند بسته به اجرا، سرعت کامپایل را به میزان قابل توجهی افزایش دهد. برای جاوا، ساخت‌ها می‌توانند ۲ تا ۴ برابر سریع‌تر باشند، گاهی اوقات برای کامپایل تدریجی بیشتر. سرعت کامپایل Bazel با کارگران حدود 2.5 برابر است. برای جزئیات بیشتر، به بخش " انتخاب تعداد کارگران " مراجعه کنید.

اگر یک محیط ساخت از راه دور نیز دارید که با محیط ساخت محلی شما مطابقت دارد، می توانید از استراتژی دینامیک آزمایشی استفاده کنید که یک اجرای از راه دور و یک اجرای کارگری را انجام می دهد. برای فعال کردن استراتژی پویا، پرچم --experimental_spawn_scheduler را ارسال کنید. این استراتژی به طور خودکار کارگران را فعال می کند، بنابراین نیازی به تعیین استراتژی worker نیست، اما همچنان می توانید از local یا sandboxed به عنوان جایگزین استفاده کنید.

انتخاب تعداد کارگران

تعداد پیش‌فرض نمونه‌های کارگر در هر یادگاری 4 است، اما می‌توان آن را با پرچم worker_max_instances تنظیم کرد. بین استفاده بهینه از CPUهای موجود و میزان کامپایل JIT و بازدیدهای حافظه نهان، تعادلی وجود دارد. با کارگران بیشتر، اهداف بیشتر هزینه‌های راه‌اندازی اجرای کدهای غیر JIT و ضربه زدن به حافظه‌های پنهان را پرداخت می‌کنند. اگر تعداد کمی هدف برای ساخت دارید، یک کارگر ممکن است بهترین مبادله را بین سرعت کامپایل و استفاده از منابع ارائه دهد (برای مثال، شماره 8586 را ببینید. پرچم worker_max_instances حداکثر تعداد نمونه های کارگر را در هر یادداشت و پرچم تعیین می کند. تنظیم کنید (پایین را ببینید)، بنابراین در یک سیستم ترکیبی، اگر مقدار پیش‌فرض را حفظ کنید، می‌توانید از حافظه بسیار زیادی استفاده کنید.

این نمودار زمان‌های جمع‌آوری از ابتدا برای Bazel (هدف //src:bazel ) را در یک ایستگاه کاری لینوکس 3.5 گیگاهرتزی Intel Xeon با 64 گیگابایت رم با بیش‌رشته‌ای نشان می‌دهد. برای هر پیکربندی کارگر، پنج ساخت تمیز اجرا می شود و میانگین چهار مورد آخر گرفته می شود.

Graph of performance improvements of clean builds

شکل 1. نمودار بهبود عملکرد ساختمان های تمیز.

برای این پیکربندی، دو کارگر سریع‌ترین کامپایل را ارائه می‌دهند، هرچند در مقایسه با یک کارگر تنها 14 درصد پیشرفت دارند. اگر می خواهید از حافظه کمتری استفاده کنید، One Worker گزینه خوبی است.

کامپایل افزایشی معمولاً مزایای بیشتری دارد. ساخت‌های تمیز نسبتاً نادر هستند، اما تغییر یک فایل بین کامپایل‌ها، به‌ویژه در توسعه مبتنی بر آزمایش، رایج است. مثال بالا همچنین دارای برخی اقدامات بسته بندی غیر جاوا است که می تواند زمان کامپایل افزایشی را تحت الشعاع قرار دهد.

کامپایل مجدد فقط منابع جاوا ( //src/main/java/com/google/devtools/build/lib/bazel:BazelServer_deploy.jar ) پس از تغییر یک رشته ثابت داخلی در AbstractContainerizingSandboxedSpawn.java سرعت 3 برابری (میانگین 20) می دهد. ساخت‌های افزایشی با حذف یک ساخت گرم‌آپ):

Graph of performance improvements of incremental builds

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

افزایش سرعت بستگی به تغییر ایجاد شده دارد. سرعت یک ضریب 6 در شرایط فوق زمانی که یک ثابت رایج مورد استفاده تغییر می کند اندازه گیری می شود.

اصلاح کارگران پایدار

می‌توانید پرچم --worker_extra_flag را برای مشخص کردن پرچم‌های راه‌اندازی به کارگران، که توسط یادگاری کلید می‌خورد، ارسال کنید. به عنوان مثال، ارسال --worker_extra_flag=javac=--debug ، اشکال زدایی را فقط برای Javac روشن می کند. در هر استفاده از این پرچم فقط یک پرچم کارگر قابل تنظیم است و فقط برای یک یادگاری. کارگران نه تنها به طور جداگانه برای هر یادگاری ایجاد می شوند، بلکه برای تغییرات در پرچم های راه اندازی آنها نیز ایجاد می شوند. هر ترکیبی از پرچم‌های یادگاری و راه‌اندازی در یک WorkerKey ترکیب می‌شود و برای هر WorkerKey تا worker_max_instances ممکن است کارگران ایجاد شوند. بخش بعدی را ببینید که چگونه پیکربندی کنش می‌تواند پرچم‌های راه‌اندازی را نیز مشخص کند.

می‌توانید از پرچم --high_priority_workers برای مشخص کردن یک یادگاری استفاده کنید که باید در اولویت اجرای یادداشت‌های با اولویت عادی باشد. این می تواند به اولویت بندی اقداماتی که همیشه در مسیر بحرانی هستند کمک کند. اگر دو یا چند کارگر با اولویت بالا درخواست‌ها را اجرا می‌کنند، از اجرای همه کارگران دیگر جلوگیری می‌شود. این پرچم را می توان چندین بار استفاده کرد.

ارسال پرچم --worker_sandboxing باعث می شود که هر درخواست کارگر از یک پوشه سندباکس جداگانه برای همه ورودی های خود استفاده کند. راه‌اندازی سندباکس ، مخصوصاً در macOS، زمان بیشتری می‌برد، اما ضمانت صحت بهتری را ارائه می‌دهد.

پرچم --worker_quit_after_build عمدتا برای اشکال زدایی و پروفایل مفید است. این پرچم همه کارگران را مجبور می کند پس از اتمام ساخت، کار را ترک کنند. همچنین می‌توانید --worker_verbose را برای دریافت خروجی بیشتر در مورد کاری که کارگران انجام می‌دهند عبور دهید. این پرچم در قسمت verbosity در WorkRequest و به پیاده‌سازی‌های کارگر اجازه می‌دهد تا پرمخاطب‌تر باشند.

کارگران گزارش های خود را در فهرست <outputBase>/bazel-workers ذخیره می کنند، به عنوان مثال /tmp/_bazel_larsrc/191013354bebe14fdddae77f2679c3ef/bazel-workers/worker-1-Javac.log . نام فایل شامل شناسه کارگر و یادگاری است. از آنجایی که در هر یادداشت می‌تواند بیش از یک WorkerKey وجود داشته باشد، ممکن است بیش از worker_max_instances فایل‌های گزارش برای یک یادگاری معین مشاهده کنید.

برای ساخت‌های اندروید، جزئیات را در صفحه عملکرد ساخت اندروید ببینید .

پیاده سازی کارگران مستمر

برای اطلاعات در مورد نحوه ایجاد کارگر، صفحه ایجاد کارگران پایدار را ببینید.

این مثال یک پیکربندی Starlark را برای کارگری که از JSON استفاده می کند نشان می دهد:

args_file = ctx.actions.declare_file(ctx.label.name + "_args_file")
ctx.actions.write(
    output = args_file,
    content = "\n".join(["-g", "-source", "1.5"] + ctx.files.srcs),
)
ctx.actions.run(
    mnemonic = "SomeCompiler",
    executable = "bin/some_compiler_wrapper",
    inputs = inputs,
    outputs = outputs,
    arguments = [ "-max_mem=4G",  "@%s" % args_file.path],
    execution_requirements = {
        "supports-workers" : "1", "requires-worker-protocol" : "json" }
)

با این تعریف، اولین استفاده از این عمل با اجرای خط فرمان /bin/some_compiler -max_mem=4G --persistent_worker می شود. یک درخواست برای کامپایل Foo.java به شکل زیر خواهد بود:

arguments: [ "-g", "-source", "1.5", "Foo.java" ]
inputs: [
  {path: "symlinkfarm/input1" digest: "d49a..." },
  {path: "symlinkfarm/input2", digest: "093d..."},
]

کارگر این را در stdin در قالب JSON محدود شده با خط جدید دریافت می کند (زیرا requires-worker-protocol روی JSON تنظیم شده است). سپس کارگر این عمل را انجام می دهد و یک WorkResponse با فرمت JSON به WorkResponse در stdout خود می فرستد. سپس Bazel این پاسخ را تجزیه می کند و به صورت دستی آن را به یک پروتو WorkResponse تبدیل می کند. برای برقراری ارتباط با کارگر مرتبط با استفاده از پروتوباف باینری کدگذاری شده به جای JSON، requires-worker-protocol روی proto تنظیم می‌شود، مانند این:

  execution_requirements = {
    "supports-workers" : "1" ,
    "requires-worker-protocol" : "proto"
  }

اگر الزامات- requires-worker-protocol در الزامات اجرا لحاظ نکنید، Bazel ارتباطات کارگر را برای استفاده از protobuf پیش‌فرض می‌کند.

WorkerKey را از یادداشت و پرچم های مشترک استخراج می کند، بنابراین اگر این پیکربندی اجازه تغییر پارامتر max_mem را می داد، برای هر مقدار استفاده شده یک کارگر جداگانه ایجاد می شود. در صورت استفاده از تغییرات بیش از حد، این می تواند منجر به مصرف بیش از حد حافظه شود.

هر کارگر در حال حاضر فقط می تواند یک درخواست را در یک زمان پردازش کند. ویژگی آزمایشی مالتی پلکس امکان استفاده از چند رشته را می دهد، اگر ابزار زیربنایی چند رشته ای باشد و پوشش برای درک این موضوع تنظیم شده باشد.

در این مخزن GitHub ، می‌توانید نمونه‌ای از wrapper‌های کارگر نوشته شده در جاوا و همچنین در پایتون را ببینید. اگر در جاوا اسکریپت یا TypeScript کار می کنید، بسته @bazel/worker و مثال کارگر nodejs ممکن است مفید باشد.

کارگران چگونه بر سندباکس تاثیر می گذارند؟

استفاده از استراتژی worker به‌طور پیش‌فرض، عملکرد را در جعبه‌شنود اجرا نمی‌کند، مشابه استراتژی local . می‌توانید پرچم --worker_sandboxing را طوری تنظیم کنید که همه کارگران داخل جعبه‌های ایمنی اجرا شوند، مطمئن شوید که هر اجرای ابزار فقط فایل‌های ورودی را می‌بیند که قرار است داشته باشد. این ابزار همچنان ممکن است اطلاعات بین درخواست‌ها را به صورت داخلی نشت کند، به عنوان مثال از طریق یک حافظه پنهان. استفاده از استراتژی dynamic مستلزم آن است که کارگران جعبه‌شنی شوند .

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

حتی زمانی که از هضم‌های ورودی برای محافظت در برابر ذخیره‌سازی ناخواسته استفاده می‌کنید، کارگران sandboxed جعبه‌شنی ماسه‌بازی دقیق‌تری نسبت به جعبه‌های ماسه‌بازی خالص ارائه می‌کنند، زیرا ابزار ممکن است حالت داخلی دیگری را که تحت تأثیر درخواست‌های قبلی قرار گرفته‌اند، حفظ کند.

کارگران Multiplex تنها در صورتی می‌توانند سندباکس شوند که پیاده‌سازی کارگر از آن پشتیبانی کند، و این sandboxing باید به طور جداگانه با پرچم --experimental_worker_multiplex_sandboxing فعال شود. جزئیات بیشتر را در سند طراحی مشاهده کنید).

بیشتر خواندن

برای کسب اطلاعات بیشتر در مورد کارگران دائمی، نگاه کنید به: