被 nss_ldap 婊到

把 FreeBSD 從 7.0-RELEASE 升級到 7.1-BETA2 以後,發現只有 Local Account 會去查該 Account 屬於 ldap 裡面的 group,而 LDAP Account 不會,只會查 Local Group 跟 Main Group(gidNumber 指定的 Group)。

找了半天,改了 nsswitch.conf 與 nss_ldap.conf,還是不會動,最後自暴自棄開始翻 Mailling list,結果看到這篇:[Working fix] Problems combining nss_ldap/pam_ldap with pam_mkhomedir in FreeBSD 7.0

Developers doesn’t like "soft".

當場囧在那邊。最後把 soft 改成 hard,這個問題就解決了….Orz

用 pf + relayd 架設 Layer 4 Switch (Server Load Balancer)

源於 OpenBSD,port 到 FreeBSD 的 pf 本身就可以作 load balancer,但是不能作 healthy check。要作 healthy check 的話,必須加上 relayd。另外用 CARP(4)PFSYNC(4) 可以做到 Active-Standby 的 Redundancy HA,也就是當一台 SLB (Server Load Balancer) 死掉的時候,另一台會自動起來提供服務。詳細的作法在參考資料有,因此這裡不贅述。基本的想法為:

  1. 用 pf 設定防火牆與 NAT,把 incoming port 80 的 destination 換成 server pool 內的任一台。
  2. 用 carp 來保證 HA。
  3. 用 pfsync 來 sync 兩台 SLB 之間的 pf firewall state。
  4. 用 relayd 來檢查 server 的狀態,如果不能連線的時候,把 server 從 pool 內拿掉。

這樣就可以達到 Layer 4 Switch 的功能,在 relayd 裡面稱為 REDIRECT 模式,缺點是 pool 內所有的 server 都必須把 default gateway 設為 SLB。
另外 relayd 也可以採用類似 haproxy 的方式,由 relayd 跟 client 與 server 各建立一個連線,作 Layer 7 的 forwarding。這在 relayd 裡面稱為 RELAY 模式。
設定 relay 模式的時候,可以對 HTTP Header 作修改,例如加上 X-Forwarded-For Header,或是根據 Host Header 或者 URI 來決定要分配到的 Pool。另外 healthy check 也可以由管理者自行撰寫 script,因此可以作比較複雜的檢查。設定方式可以參考 RELAYD.CONF(5)

比起 haproxy 來說,relayd 可以輕易的達到 Full Transparent Proxy (後端的 Server 看到的 source ip 是真正的 ip)的功能而不需要 patch kernel,而且也可以作 graceful restart( haproxy 在 restart 的時候服務會中斷);不過 haproxy 有許多的實例已經驗證過它的效能,可以吃滿 10Gbps 網路,但 relayd 在 RELAY 模式的 效能還是未知數。另外,由於 relayd 與 pf 綁的很緊,因此目前只有 OpenBSD 與 FreeBSD 版,不能在 Linux 上執行。

參考資料:

在一顆硬碟上同時作 gmirror 與 ZFS

情形:有兩顆同樣大小的硬碟,想切出 10G 當 / 並作 gmirror,其他作 ZFS。

作法:先灌好 FreeBSD,把硬碟切成同一個 partition,例如說 ad0s1。 / 放在 ad0s1a,swap 放在 ad0s1b,ZFS 放在 ad0s1d。假設另一顆硬碟是 ad1,也同樣切成 a,b,d 三個與 ad0 slice 大小相同的 slice。

# gmirror load
# gmirror label -v -h -b round-robin gm0s1a ad1s1a
# newfs -U -O2 /dev/mirror/gm0s1a
# mount -o noatime /dev/mirror/gm0s1a /mnt
# echo ‘geom_mirror_load="YES"’ >> /boot/loader.conf
# vi /etc/fstab

把 /dev/ad0s1a 都改成 /dev/mirror/gm0s1a

# cd /
# tar -c –one-file-system -f – . | tar xpf – -C /mnt/

重開後,再把 ad0s1a insert 回去:

# gmirror insert gm0s1a ad0s1a
# gmirror rebuild gm0s1a ad0s1a

接著建立 ZFS:

# zpool create tank ad0s1d ad1s1d

這樣就完成了。

FreeBSD: 用 ZFS 的 volume 當作 iSCSI Target

簡單的說,可以把 iscsi-target 的 extent 設成 ZFS 的 volume 就可以了…
不過我不知道如果 extent 的大小設超過 iscsi-target 會發生什麼事。

# zfs create -V 10g tank/iscsi
# cd /usr/ports/net/iscsi-target/ ; make install clean
# cat > /usr/local/etc/iscsi/targets
extent0         /dev/zvol/tank/iscsi     0       10GB
target0         rw      extent0         10.0.0.0/24
^D
# /usr/local/etc/rc.d/iscsi_target forcestart

這樣就可以用別的 iSCSI initiator 來連接 iSCSI Target 了。

MySQL (MyISAM) 的備份

當系統小的時候,用 mysqldump 在離峰時間把資料 dump 出來還算可行。
雖然 Table 會暫時 Lock 住,但是因為小,所以速度可以很快,鎖住的時間可以不計。
但當系統大的時候就不能這樣做了。

好在已經有許多處理這個問題的經驗者。
解決這個問題的 Key Point 是「減少鎖 Table 的時間」,因此如果採用的 File System 或是 Volume Manager 有支援快速的 snapshot 功能的話,整個問題就簡單很多。步驟如以下所示:

  1. SLAVE STOP;
  2. FLUSH TABLE WITH READ LOCK;
  3. 作 snapshot
  4. UNLOCK TABLES;
  5. SLAVE START;

如果採用 LVM (Linux), ZFS (FreeBSD, Solaris) 或是 NetApp 的話,整個備份過程可以小於 5 秒鐘,因此可以做到每個小時備份一次而不影響正常使用。如果在 Slave 上做 snapshot 備份,則完全不會影響到寫入(READ LOCK時還是可以讀)。

FreeBSD: vfs.read_max for RAID

Tested with: bonnie -s 2048, FreeBSD 7.0 UFS2 , Hardware RAID 5 (6 PATA 7200rpm 250G disks)
vfs.read_max=8 (default)

             -------Sequential Output--------  
             -Per Char- --Block--- -Rewrite-- 
Machine   MB K/sec %CPU K/sec %CPU K/sec %CPU   
        2048 25812 24.8 26483  6.6 13886  4.4   
             ---Sequential Input-- --Random--
             -Per Char- --Block--- --Seeks--- 
             K/sec %CPU K/sec %CPU  /sec %CPU 
             32162 32.5 33386  5.1 232.3  1.5

vfs.read_mas=128

             -------Sequential Output--------
             -Per Char- --Block--- -Rewrite--
Machine MB   K/sec %CPU K/sec %CPU K/sec %CPU 
        2048 25380 24.3 25949  6.5 13956  4.3  
             ---Sequential Input-- --Random--
             -Per Char- --Block--- --Seeks---
             K/sec %CPU K/sec %CPU  /sec %CPU
             41060 43.4 42839  8.3 224.9  1.4

            

vfs.read_max=256

             -------Sequential Output--------
             -Per Char- --Block--- -Rewrite-- 
Machine   MB K/sec %CPU K/sec %CPU K/sec %CPU 
        2048 25714 24.3 25939  6.5 13966  4.3  
             ---Sequential Input-- --Random-- 
             -Per Char- --Block--- --Seeks---
             K/sec %CPU K/sec %CPU  /sec %CPU
             41442 43.8 43737 8.6  225.2  1.5 
       

結論:調整 vfs.read_max 對 random 存取的效能沒有太大幫助,而對 sequential read access 則有 25% 的效能增進。