وفقًا لـ هذه المقالة على Medium، فإن الاتصال عبر Sokت النطاق يونكس أسرع بحوالي 20% مقارنة باستخدام Sokتات TCP…
أيضًا، استخدام Sokتات النطاق يونكس سيُسهّل تشغيل حاويات مستقلة متعددة دون فصل حاويات الويب عن حاويات البيانات… وإلا، أعتقد أنك ستواجه تضاربات مع Redis المستمع على 127.0.0.1…
أحاول حاليًا إعداد حاويتين مستقلتين تمامًا على مضيف واحد، وبما أنهما مخصصتان لمواقع صغيرة جدًا، فأنا أفضل مرونة إبقائهما في حاويات مستقلة… للأسف، استماع Redis على 127.0.0.1 (وربما Postgres أيضًا) سيُسبب تضاربات…
كما تلاحظ، فإن خدمة ريديس تستمع على localhost داخل الحاوية؛ و localhost داخل الحاوية لم يتم (ولا يتم) تعريضها خارج الحاوية.
لذلك، إذا كان لديك العديد من حاويات discourse المستقلة قيد التشغيل، فلن توجد أي تعارضات بين الحاويات فيما يتعلق بخدمة ريديس، لأن خدمة ريديس لم تُعرَّض خارج كل حاوية.
لهذا السبب تُسمى “حاوية”…
يجب تعريض كل مقبس (socket) داخل الحاوية بشكل صريح ليصبح متاحًا خارجها.
آمل أن يكون هذا مفيدًا ولو بشكل بسيط.
لاحظ أن مقابس نطاق يونكس (Unix domain sockets) رائعة جدًا… لقد تناولت فقط تعليقك حول التعارضات المتصورة بين حاويات ريديس المستقلة، ولم أتطرق إلى موضوع مقابس نطاق يونكس.
هذا ما كنت أتخيل أنه سيحدث عند تشغيل discourse داخل Docker أيضًا، ومع ذلك، عندما قمت بتشغيله فعليًا، رأيت أثناء عملية التمهيد:
INFO -- : > cd /var/www/discourse && git reset --hard
# oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
# Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=195, just started
# Configuration loaded
# Could not create server TCP listening socket *:6379: bind: Address already in use
Checking out files: 100% (27893/27893), done.
وقد وجدت هذا الموضوع حول “فشل التثبيت بسبب حاوية Redis أخرى”, ولكن المشكلة الفعلية كانت نقص مساحة القرص… قمت بإعادة تنظيم بعض الأشياء، ويعمل الآن بشكل ممتاز مع حاويات مستقلة متعددة.
من الرائع أن نقرأ أنك قد عثرت على المشكلة الجذرية وأدركت الآن أن Redis يعمل “داخل الحاوية” ولا يتم تعريضه (من منظور إدخال/إخراج المقبس) خارج الحاوية (كما هو مضبوط افتراضيًا من الصندوق).
بشأن استخدام مقابس النطاقات المحلية (unix domain sockets) مع Redis، أعتقد أن هذه فكرة ممتازة. لم أقم بإعداد ذلك بعد، ولم أقرأ أي تقرير يشرح كيفية إعداده لـ Discourse، لذا أشجعك على مواصلة استكشاف هذا الخيار.
إذا توفّر لي الوقت، سأقوم بالبحث في هذا الأمر أكثر وحاول إعداد Redis لاستخدام مقبس نطاق محلي في Discourse على خادم تجريبي. وفي غضون ذلك، إذا تمكنت من حل هذه المسألة ونشر نتائجك، فسأكون ممتنًا للغاية. أنا متأكد من أن الكثيرين آخرين مهتمون أيضًا بهذا الموضوع المثير حول Redis.
هل لاحظ أي شخص آخر أن REDIS_URL لم يعد له أي تأثير؟ أثناء إعادة البناء (rebuild) وأيضًا عند بدء تشغيل الحاوية، على الرغم من تعيين REDIS_URL للاتصال عبر مقبس UNIX، فإنه يحاول الاتصال عبر redis://localhost:6379.
من ناحية، هذا منطقي، نظرًا لأن Discourse لديه إعدادات ويطبق المضيف والمنفذ فقط: discourse/app/models/global_setting.rb at main · discourse/discourse · GitHub
سيكون هناك معلمة path لتحديد مسار مقبس UNIX، والذي سيتجاوز المضيف والمنفذ. وسيكون هناك معلمة url، لتحديد عنوان URL كامل مثل unix:///shared/redis_data/redis.sock.
يتم تمرير متغير البيئة بشكل صحيح بالمناسبة. تركته في مكانه وقمت فقط بتكوين Redis لعدم الاستماع على مقبس UNIX، وبينما يبدأ Unicorn بشكل جيد، يفشل Sidekiq، ويفتقد مقبس UNIX بدلاً من ذلك :
Error in demon processes heartbeat check: No such file or directory - connect(2) for /shared/redis_data/redis.sock
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client/ruby_connection.rb:116:in `initialize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client/ruby_connection.rb:116:in `new'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client/ruby_connection.rb:116:in `connect'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client/ruby_connection.rb:51:in `initialize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client.rb:759:in `new'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client.rb:759:in `block in connect'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client/middlewares.rb:12:in `connect'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client.rb:758:in `connect'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client.rb:745:in `raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client.rb:705:in `ensure_connected'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/redis-client-0.24.0/lib/redis_client.rb:285:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/redis_client_adapter.rb:36:in `block (2 levels) in <module:CompatMethods>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/api.rb:912:in `block in cleanup'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/config.rb:175:in `block in redis'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/connection_pool-2.5.3/lib/connection_pool.rb:110:in `block (2 levels) in with'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/connection_pool-2.5.3/lib/connection_pool.rb:109:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/connection_pool-2.5.3/lib/connection_pool.rb:109:in `block in with'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/connection_pool-2.5.3/lib/connection_pool.rb:106:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/connection_pool-2.5.3/lib/connection_pool.rb:106:in `with'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/config.rb:172:in `redis'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq.rb:74:in `redis'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/api.rb:912:in `cleanup'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/api.rb:903:in `initialize'
/var/www/discourse/lib/demon/sidekiq.rb:25:in `new'
/var/www/discourse/lib/demon/sidekiq.rb:25:in `heartbeat_check'
config/unicorn.conf.rb:131:in `block (2 levels) in reload'
يتناسب هذا مع الصورة التي تفيد بأن REDIS_URL لا يزال يعمل، ولكن فقط إذا لم يتم تعريف إعدادات الاتصال بطريقة أخرى. بالنظر إلى تتبع الخطأ، لا يطبق global_setting.rb المضيف والمنفذ لـ Sidekiq، كما يفعل لـ Unicorn.