1. Chuẩn bị phần cứng và tối ưu hoá Anti-spam/Anti-virus.

– Khuyến nghị nên sử dụng ảo hoá. Các máy ảo được tạo với các tuỳ chọn  phù hợp với khuyến nghị của các nền tảng ảo hoá khác nhau (ví dụ như cách chọn loại card mạng, bỏ bớt các thiết bị như đĩa mềm, v.v…).

– Sử dụng các loại ổ đĩa đáp ứng hiệu năng yêu cầu của Mailbox server: khuyến nghị ổ đĩa SAS hoặc SSD. Thông thường, chúng tôi không khuyến cáo sử dụng 1 server (máy ảo) quá lớn, khi hệ thống lớn lên, chúng tôi sẽ triển khai thêm server. Một zimbra server cho 10000 mailbox của chúng tôi có RAM thường là 32GB và tối đa là 64GB.

– Zimbra thường không sử dụng nhiều CPU ngoại trừ các lúc cao điểm: chúng tôi thường sử dụng 2 cpu, mỗi cpu tối đa 8 core.

– Sử dụng các phân vùng ổ cứng/các HDD khác nhau cho các thư mục quan trọng của Zimbra. Zimbra có các thư mục sau sẽ tiêu tốn nhiều I/O: ~/backup, ~/data, ~/db, ~/store.

– Nếu sử dụng chức năng antispam/antivirus của Zimbra (Spamassasin, Clamav), khuyến nghị tạo RAM disk trên MTA server.

– Khuyến nghị offload phần antispam/antivirus sang 1 server/ứng dụng ngoài Zimbra nhằm giảm tải cho hệ thống (như bạn đã biết, 80% email đến thường là các mail rác). Có thể sử dụng các mail secure gateway của Barracuda, Fortinet hoặc dùng các dịch vụ trên cloud như Mimecast, spamtitan. Hiện tại Zimico đang cung cấp dịch vụ chống spam chuyên nghiệp với chi phí rất thấp từ Spamhero.

– Sử dụng các tool như top để giám sát các thông số như:

+ id: thể hiện % của idle cpu cycles (liên quan đến CPU).

+ wa: thể hiện % trạng thái đợi (liên quan đến I/O ổ đĩa).

+ st: thể hiện % steal time (liên quan đến hạ tầng ảo hoá).

+ KiB Swap > used: hiển thị mức sử dụng swap file (liên quan đến RAM).

– Sử dụng kiến trúc multiserver phù hợp (ngoài phạm vi bài viết này).

Dưới đây là các thông số cụ thể giúp bạn tối ưu hoá zimbra:

2. Tối ưu hoá hệ điều hành.

a. swap file.

Tốt nhất nên có 2 swap file trên 2 partion (nằm trên 2 ổ/cụm ổ đĩa vật lý khác nhau), kích thước swap file nên bằng kích thước RAM. Ví dụ với server có 32GB RAM, thiết lập 2 swap file 16GB.

b. Tinh chỉnh kernel.

Thêm các dòng sau vào /etc/sysctl.conf

# Reduce Swappiness and Other Tuning
vm.swappiness = 1
vm.min_free_kbytes = 524288
vm.vfs_cache_pressure=200
# To effect changes after updating this file, execute "sysctl -p" as root

3. Tối ưu hoá database trên mailbox servers (32GB RAM).

Tiến hành kiểm tra thông số mặc định và thay đổi nếu cần thiết. Các thông số đề xuất dưới đây đã được kiểm tra trên mailbox server có khoảng 10000 account.

Thay đổi các thông số sau cho MariaDB trong /opt/zimbra/conf/my.cnf (tham khảo tài liệu chi tiết tại đây)

max_connections = 440
innodb_buffer_pool_size = 26624M
innodb_open_files = 11000
table_open_cache = 5000

Để điều chỉnh các thông số trên cho phù hợp, bạn cần:

a. Tải mysqltuner.pl và chạy để lấy thông tin về InnoDB. Lưu ý không thực hiện bất kỳ điều chỉnh nào theo khuyến nghị của tool này.

Với quyền root, chạy:
wget mysqltuner.pl && mv index.html /opt/zimbra/mysqltuner.pl && chmod +x /opt/zimbra/mysqltuner.pl && chown zimbra.zimbra /opt/zimbra/mysqltuner.pl && su - zimbra
./mysqltuner.pl

Chú ý đến kết quả đầu ra, ví dụ như:

[!!] InnoDB buffer pool / data size: 17.0G / 23.3G

Dòng trên báo cho ta biết kích thước tổng của InnoDB database là 23.3G nhưng ta chỉ đang cấp 17.0G cho MariaDB. Như vậy là đang thiếu RAM vật lý và MariaDB sẽ phải dùng ổ cứng để đệm. Rất nhiều data sẽ phải di chuyển qua lại giữa RAM và disk và gây chậm hệ thống.

b. Tinh chỉnh MariaDB.

Để khắc phục điều này, bạn thay đổi thông số innodb_buffer_pool_size = 2662M (tương đương khoảng 25GB) trong my.cnf file như trên. Thông số innodb_buffer_pool_size được tính bằng khoảng 110-125% kích thước data size mà tool mysqltunner.ple báo (trong trường hợp trên là 23.3G). Thông số này được thiết lập từ lúc cài Zimbra lần đầu và không được cập nhật tự động khi bạn tăng RAM, bạn cần điều chỉnh sau mỗi lần tăng RAM cho hệ thống.

Zimbra khuyến cáo tổng RAM phân bổ cho MariaDB và Java heap không vượt quá 80% RAM vật lý của server. Như vậy ta cần kiểm tra xem có cần phải tăng RAM vật lý trên server hay không.

Kiểm tra lượng RAM mà hệ thống đang gán cho Java heap.

$ zmlocalconfig mailboxd_java_heap_size
mailboxd_java_heap_size = 6144

Thông số mailboxd_java_heap_size cũng được gán từ khi cài đặt Zimbra và được giữ nguyên không thay đổi. Để biết khi nào cần thay đổi thông số này, bạn cần kiểm tra trong zmmailboxd.out các dòng sau:

[313905.682s][info][gc] GC(172536) Pause Young (Normal) (G1 Evacuation Pause) 4770M->1512M(6144M) 40.579ms
[313913.513s][info][gc] GC(172537) Pause Young (Normal) (G1 Evacuation Pause) 4812M->1473M(6144M) 35.362ms
[313921.516s][info][gc] GC(172538) Pause Young (Normal) (G1 Evacuation Pause) 4913M->1477M(6144M) 29.879ms

Về cơ bản, nếu trình GC (Garbage Collector) chạy vài giây một lần thì bạn vẫn ổn. Nếu trình thu gom rác chạy đều đặn mỗi giây (thông số thời gian phía bên trái) và thời gian tạm dừng lớn hơn 100 mili giây (thông số hiển thị phía bên phải cuối dòng log) thì có lẽ đã đến lúc tăng kích thước vùng heap Java. Trong hầu hết các trường hợp, 6GB-8GB là đủ.

Dấu thời gian ở bên trái cho thấy các lần dọn dẹp này diễn ra cách nhau khoảng 8 giây (tốt!). Di chuyển về phía bên phải, chúng ta thấy rằng trình thu gom rác GC (được lập trình để kích hoạt khi bộ nhớ heap đầy ~ 75%) bắt đầu xử lý khi heap có 4,7GB đến 4,9GB đối tượng trong đó. Sau khi loại bỏ các đối tượng không sử dụng và chống phân mảnh vùng heap (quá trình này mất từ 29 mili giây đến 40 mili giây), mức tiêu thụ vùng heap Java đã giảm xuống còn khoảng 1,5 GB, với kích thước vùng heap tối đa được đặt thành 6GB.

Nếu zmmailboxd.out cho thấy các hoạt động GC diễn ra vài lần trong vài giây và/hoặc sau khi xử lý các đối tượng được sử dụng hiện tại giống như 4GB thay vì 1,5 GB và/hoặc thời gian xử lý đó lớn hơn 100 mili giây, thì cần tăng kích thước vùng heap java, được thiết lập thông qua localconfig của Zimbra.

$ zmlocalconfig -e mailboxd_java_heap_size 6144

Như vậy tổng RAM đang gán cho MariaDB và Java heap là 25GB + 6GB = 31GB, kết hợp với điều kiện 80% suy ra tổng RAM vật lý mà server cần là 36GB. Tức là nếu chưa có đủ RAM cho server thì bạn cần phải gắn thêm RAM.

c. Các thông số khác

Để điều chỉnh thông số như innodb_open_files và table_open_cache, ta xem trong MariaDB:

$ mysql
MariaDB [(none)]> show global status like 'opened_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_tables | 4422  |
+---------------+-------+
1 row in set (0.00 sec)
MariaDB [(none)]> quit
Bye

Thông số mặc định table_open_cache của zimbra là 1200, ta điều chỉnh tăng lên 5000. Ta giám sát thông số Opened_tables trong 1 tuần và tăng lên đáp ứng.

Theo tài liệu tối ưu hoá của zimbra, ta có thể điều chỉnh thêm các thông số tmp_table_size, max_heap_table_size, table_definition_cache và innodb_io_capacity.

tmp_table_size có thông số mặc định là 16MB. Để giảm thời gian ghi đọc trên ổ đĩa, ta sẽ tăng giá trị thông số này lên để dùng RAM nhiều hơn. Thêm 2 dòng sau vào cuối file ~/conf/my.cnf, 2 thông số này cần giống nhau:

tmp_table_size = 64M
max_heap_table_size = 64M

Với việc tăng tmp_table_size từ 16MB lên 64MB sẽ cần thêm 5GB RAM, bạn có thể tăng lên 32MB trước và giám sát kết quả qua tool mysqltuner.pl.

[OK] Highest usage of available connections: 48% (53/110)
<...>
[OK] Temporary tables created on disk: 11% (11K on disk / 101K total)

Thông số tiếp theo là table_definition_cache. Đây là thông số chứa meta data của các table được MariaDB mở trong RAM. Ta cũng tăng lên tương ứng với thông số table_open_cache. Mặc định table_definition_cache = 400, ta sẽ tăng lên 1800.

table_definition_cache = 1800

Thông số cuối cùng cần xem xét là innodb_io_capacity. Đây là thông số cho biết mức IOP tối đa mà InnoDB sẽ dùng. Với các ổ đĩa SATA thì giá trị mặc định 200 là phù hợp. Nếu bạn đang dùng ổ đĩa SSD, Raid6 mức IOP của ổ đĩa này là khoảng 3000 IOPS, bạn có thể cân nhắc tăng giá trị của innodb_io_capacity lên 2000.

innodb_io_capacity = 2000

4. Thay đổi các thông số trên zimbra.

1. Gửi thông báo cho người dùng ngay khi quota bị hết
$ zmprov mcf zimbraLmtpPermanentFailureWhenOverQuota TRUE

2. Thông báo cho người dùng khi email không gửi đi được.
$zmprov mcf zimbraMtaDelayWarningTime 10m

3. Thay đổi các thông số mức ngưỡng kết nối.
$ zmlocalconfig -e zimbra_mysql_connector_maxActive=1000
$ zmlocalconfig -e mailboxd_java_heap_size=12288
$ zmlocalconfig -e servlet_max_concurrent_http_requests_per_account=20
$ zmlocalconfig -e zimbra_mailbox_lock_max_waiting_threads=100
$ zmlocalconfig -e zimbra_mailbox_lock_timeout=60
$ zmlocalconfig -e zimbra_session_limit_imap=200
$ zmlocalconfig -e zimbra_waitset_max_per_account=10
$ zmprov ms `zmhostname` zimbraLmtpNumThreads 200
$ zmprov ms `zmhostname` zimbraImapNumThreads 3000
$ zmprov ms `zmhostname` zimbraImapMaxConnections 5000
$ zmprov ms `zmhostname` zimbraPop3NumThreads 1000
$ zmprov ms `zmhostname` zimbraPop3MaxConnections 3000
$ zmprov ms `zmhostname` zimbraHttpNumThreads 10000
$ zmprov ms `zmhostname` zimbraHttpDosFilterMaxRequestsPerSec 2000
$ zmprov ms `zmhostname` zimbraImapInactiveSessionEhcacheSize 104857600
$ zmprov ms <proxy_server> zimbraReverseProxyUpstreamReadTimeout 180s
$ zmprov ms <proxy_server> zimbraReverseProxyWorkerProcesses 8
4. Thay đổi thời gian tự động lưu bản nháp trên webmail, ví dụ áp dụng cho defaul cos, thực hiện tương tự cho các cos khác.
$ zmprov mc default zimbraPrefAutoSaveDraftInterval 120s

5. Tối ưu hoá cho mta server đang sử dụng 16GB RAM, 4 CPU.

– Nên tách riêng mta server khỏi mailbox server nếu lượng traffic của bạn là rất lớn, khoảng trên 10000 message/giờ.

– Tạo RAM disk trên mta server.

Cấu hình ramdisk dùng 1,5GB. Thêm vào /etc/fstab
vi /etc/fstab
tmpfs /opt/zimbra/data/amavisd/tmp tmpfs defaults,noexec,nodev,nosuid,size=1536m,mode=750,uid=zimbra,gid=zimbra 0 0
Khởi động lại server.

– Thay đổi các thông số

1. Cấu hình postfix để ngăn chặn 1 account bị hack có thể gửi quá nhiều mail ra ngoài cũng như chặn các server bên ngoài gửi quá nhiều mail đến zimbra.
$ postconf -e smtpd_client_connection_count_limit=10
$ postconf -e smtpd_client_connection_rate_limit=25
$ postconf -e smtpd_client_message_rate_limit=25
$ postconf -e smtpd_client_recipient_rate_limit=100
$ postconf -e smtpd_client_new_tls_session_rate_limit=25
$ postconf -e smtpd_client_auth_rate_limit=5
$ postconf -e default_destination_rate_delay=1s

2. Chặn không cho người dùng gửi 1 email cho quá 50 người nhận. Bạn có thể thay đổi các thông số cho phù hợp.
$ postconf -e smtpd_recipient_limit=49
$ postconf -e smtpd_recipient_overshoot_limit=1

– Nếu đang sử dụng cbpolicyd (xem hướng dẫn tại đây), chỉnh sửa các thông số sau cho phù hợp.

$ zmprov mcf zimbraCBPolicydMinServers 8
$ zmprov mcf zimbraCBPolicydMinSpareServers 8
$ zmprov mcf zimbraCBPolicydMaxSpareServers 16
$ zmprov mcf zimbraCBPolicydMaxServers 200

6. Tắt updatedb cho các thư mục zimbra. (tham khảo tại đây)

updatedb là tiện ích quản lý cơ sở dữ liệu được sử dụng bởi tiện ích mlocate trên hệ điều hành Linux (tức là lệnh “locate”). Nó được cài đặt mặc định trên Ubuntu, nhưng có thể cài đặt tùy chọn trên CentOS/RHEL. Hằng ngày, tập lệnh mlocate gọi updatedb sẽ được thực thi như một trong các tập lệnh trong /etc/cron.daily.

updatedb sử dụng rất nhiều bộ nhớ RAM và tài nguyên CPU để theo dõi tất cả các thay đổi trong hệ thống tệp tin mỗi khi nó chạy mỗi 24 giờ. Điều này giúp tiện ích mlocate có thể tìm kiếm tập tin nhanh chóng.

Tuy nhiên, Zimbra không phụ thuộc vào tiện ích mlocate. Ví dụ, crontab của Zimbra chứa các mục sử dụng lệnh “find”, không phải lệnh “locate”. Ta sẽ báo cho OS biết không cần quét và update các thư mục của Zimbra. Trên Ubuntu, chỉ cần thêm “/opt” vào trường PRUNEPATHS trong tập tin /etc/updatedb.conf để nó trông giống như sau:

# cat /etc/updatedb.conf
PRUNE_BIND_MOUNTS="yes"
# PRUNENAMES=".git .bzr .hg .svn"
PRUNEPATHS="/opt /tmp /var/spool /media /home/.ecryptfs /var/lib/schroot"
PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs shfs sysfs cifs lustre tmpfs usbfs udf fuse.glusterfs fuse.sshfs curlftpfs ecryptfs fusesmb devtmpfs"