ردیس یک محدودیت خیلی مهمی داره و اون اینکه single thread و برای همین نمیتونه بیشتر از یک core از پردازشگر رو استفاده کنه. یکی از راهحلهای روتین استفاده از کلاستر ردیس که عملا اطلاعات بین چند node ردیس پخش میشه(sharding). نکته مهم اینه که در این مدل شما چند نود ردیس به شکل master دارید که هر کدوم از اونها باید دست کم یک slave داشته باشند تا در صورتیکه یک نود به هر دلیل از دسترس خارج شد، نود slave به صورت خودکار وارد بازی بشه.
در این پروسه هیچ تضمینی برای اینکه اطلاعات از دست نره (در زمان از دست رفتن نود master) وجود نداره! دلیلش اینه که شما اطلاعات رو روی node مستر مینویسید، نود مستر به کلاینت میگه اوکی دیتا رو دارم و بعد تازه میره دنبال اینکه دیتا روی نود slave هم ذخیره بشه. :)
این رو هم بگم که برای اینکه دیتا به شکل مساوی بین node های مستر پخش بشه، کلاستر ردیس از چیزی به اسم SLOT استفاده میکنه. در مجموع ۱۶۳۸۴ اسلات ردیس کلاستر داره که بسته به تعداد node هایی که داریم میاییم اسلات ها رو بین نودها تقسیم میکنیم.
کلاینت در صورتی که به یک node (مستر) درخواست بده واطلاعات روی اون نباشه، بجای اینکه کلید درخواستی رو بده، اطلاعات nodeی رو که کلید داره رو میده و دوباره کلاینت باید به اون دومی درخواست بده :) و این میشه همون سربار یا overhead که ردیس کلاستر به ردیس معمولی داره بعلاوه اینکه یک سری محدودیت ها رو هم خواهید داشت مثل اینکه نمیشه از قابلیت Geo location ردیس استفاه کنید .
حالا نکته اینجاس که اگر کلاینت به یک نود مستر وصل شه و اون نود به هر دلیل داون بشه، هر چند slave به شکل خودکار تبدیل به مستر میشه، اما دیگه کلاینت از اون نود اطلاعی نداره! برای حل این مشکل از لودبالانس HAPROXY استفاده میکنیم.
خودم haproxy رو به دلایل خیلی زیادی با داکر همیشه بالا میارم که کار رو خیلی ساده میکنه و برای اینکار هم لازم نیست همه چی رو از اول بسازیم، از یک داکر اماده استفاده میکنیم.
1 |
git clone https://github.com/nuved/docker-haproxy-letsencrypt.git |
و بعد باید اون رو build کنیم.
1 |
docker build –t ha . |
قبل از اجرای تنظیمات باید یک کانفیگ haproxy ایجاد کنیم که اون رو به خورد کانتینر بدیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
vi /etc/haproxy/haproxy.cfg global log /dev/log local0 info log /dev/log local1 notice chroot /var/lib/haproxy group haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s maxconn 2000000 nbproc 6 cpu–map 1 1 cpu–map 2 2 cpu–map 3 3 cpu–map 4 4 cpu–map 5 5 cpu–map 6 6 defaults REDIS log global mode tcp timeout connect 3s timeout client 6s timeout server 6s frontend ft_redis bind 172.17.77.34:6379 name redis maxconn 2000000 default_backend bk_redis mode tcp option tcplog backend bk_redis option tcp–check tcp–check send PING\r\n tcp–check expect string +PONG tcp–check send info\ replication\r\n tcp–check expect string role:master tcp–check send QUIT\r\n tcp–check expect string +OK server redis–49–6380 172.17.77.49:6380 check inter 1s server redis–47–6379 172.17.77.47:6379 check inter 1s server redis–48–6379 172.17.77.48:6379 check inter 1s server redis–49–6379 172.17.77.49:6379 check inter 1s server redis–48–6380 172.17.77.48:6380 check inter 1s server redis–47–6380 172.17.77.47:6380 check inter 1s listen stats bind 172.17.77.34:1936 mode http stats hide–version stats enable stats uri / stats realm HAProxyStatistics stats auth novid:password |
بخش frontend باعث میشه haproxy روی پورت ۶۳۷۹ لیستن کنه و هر ترافیکی هم که به سمتش بیاد رو به backend پیشفرضی که تعریف کردیم، بفرسته.
در بخش backend که قلب اصلی سیستم، haproxy به نودهای فقط master ترافیک رو میفرسته. نکته قشنگ کار اینه که در اینجا همه نود های redis چه مستر و چه slave رو میدیم و از haproxy میخوایم بره وضعیت نودها رو خوش در بیاره. haproxy هم هر یک ثانیه میره از نودهای ردیس میپرسه که شما مسترسی یا salve و اونها هم اگر جواب بدند مستر، به رنگ سبز در میان و اگر slave باشند دیگه از دور خارج میشند و عملا ترافیکی به سمت اونها نمیره :)
در بخش stats هم که صرفا امار haproxy رو فعال کردیم و کار مهمی انجام نمیده، بخش اول nbproc هم نمایانگر تعداد core های سرور و اینجا با فرض اینکه سرور هفت core پردازشی داره، شش تا از اونها رو بدین شکل به خورد haproxy میدیم :) haproxy هم مشابه nginx میاد به تعداد core هایی که مشخص کردیم child میسازه.
1 2 3 4 5 6 7 8 9 10 |
root 1365 0.0 0.4 356360 4248 ? Sl 05:15 0:00 \_ docker–containerd–shim a260b62f4a7fdc12df941a3747cda7580233c47f26a3a60b0dfa3ff2e4561665 /var/run/docker/libcontainerd/a260b62f4a7fdc12df941a3747cda7580233c47f26a3a60b0dfa3ff2e4561665 docker–runc root 1383 0.0 0.0 17980 536 ? Ss 05:15 0:00 \_ /bin/bash /entrypoint.sh root 1406 17.6 0.1 184696 1312 ? Ssl 05:15 62:43 \_ /usr/sbin/rsyslogd root 1913 17.9 0.8 227584 8524 ? Ss 05:27 61:25 \_ haproxy –f /etc/haproxy/haproxy.cfg –D –p /var/run/haproxy.pid –sf 44 45 46 47 48 root 1914 40.3 0.8 228788 8844 ? Rs 05:27 137:50 \_ haproxy –f /etc/haproxy/haproxy.cfg –D –p /var/run/haproxy.pid –sf 44 45 46 47 48 root 1915 9.4 0.7 227040 8084 ? Ss 05:27 32:25 \_ haproxy –f /etc/haproxy/haproxy.cfg –D –p /var/run/haproxy.pid –sf 44 45 46 47 48 root 1916 12.0 0.7 227312 8020 ? Ss 05:27 41:15 \_ haproxy –f /etc/haproxy/haproxy.cfg –D –p /var/run/haproxy.pid –sf 44 45 46 47 48 root 1917 29.6 0.8 228508 8336 ? Ss 05:27 101:15 \_ haproxy –f /etc/haproxy/haproxy.cfg –D –p /var/run/haproxy.pid –sf 44 45 46 47 48 root 1918 8.5 0.7 226068 7820 ? Ss 05:27 29:18 \_ haproxy –f /etc/haproxy/haproxy.cfg –D –p /var/run/haproxy.pid –sf 44 45 46 47 48 root 1921 0.0 0.0 6356 84 ? S 05:27 0:00 \_ inotifywait –q –r —exclude \.git/ –e modify,create,delete,move,move_self /etc/haproxy/haproxy.cfg /etc/letsencrypt |
و در نهایت داکر ha رو با کامند زیر اجرا میکنیم.
1 |
docker run –d —name=haproxy —ulimit nofile=4500000:4500000 –v /var/lib/haproxy:/var/lib/haproxy –v /etc/haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg –v /dev/log:/dev/log —net=host ha |
یک قابلیت خوب این کانتینر اینه که میشه کانفیگ haproxy روی سرور اصلی رو ویرایش کرد، کانتینر به شکل خودکار متوجه این امر میشه و در صورتی که مشکلی در سینتکس وجود نداشته باشه، تغییر رو اعمال میکنه. برای اینکه از این قابلیت استفاده کنید باید تغییری در ادیتور vim بدیم.
1 2 3 |
vi /root/.vimrc set backupcopy=yes |
و در نهایت اینکه اگر سرورتون زیر بار خیلی زیادی حتما تنظیمات زیر داخل sysctl فراموش نشه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
vi /etc/sysctl.conf vm.swappiness=5 fs.file–max = 10000000 fs.nr_open = 10000000 net.ipv4.tcp_mem = 786432 1697152 1945728 net.ipv4.tcp_rmem = 4096 4096 16777216 net.ipv4.tcp_wmem = 4096 4096 16777216 net.ipv4.ip_local_port_range = 1000 65535 net.nf_conntrack_max = 1200000 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 15 |
دیدگاهتان را بنویسید