丹道體悟:談丹功修煉中,對抗意念的運用!

 

丹道體悟:談丹功修煉中,對抗意念的運用!
在丹功修煉中,有種比較特殊的心理現象,即讓兩相反的意念在同一時限內一起運演,而且是十分和諧、協調比如:《道鄉集》的《養胎功法》雲:“藥入中宮後,仍以寂照主。但此時之寂照,必寂而照,照而寂,不寂不照,不照不寂,寂照至極處,自有天然之火候,自然之運動,不須神馭,不須息吹,如天地之氣自行運用而不息也。”
一般而論,“寂”屬靜態,“照”屬動態,二者顯系對立。既然心裡繫念寂靜,便不可能“照”,既然心裡繫念神照,便不可能“寂”。
但是,在內丹修持中,這兩種對抗的意念,卻可以協同運演。《道鄉集》還特別指出“寂照為養胎之、本”,可見它在丹功中的重要作用。
《悟真外篇》的《交會論》有一段“採取交會口訣”:“忘裡覓,覓裡忘,忘中見,見中忘,陽生矣;忘中采,采中忘,忘裡升,升裡見,見裡變,鉛成矣;定中起,意中升,忘中用,鉛引汞矣;鉛合汞於內,精會神於外,交會矣;鉛汞精神,合二為一,卻將一念使之落黃庭,歸鼎矣。”
這裡的“忘”、“覓”、“見”、“采”、“用”等顯系對抗的意念,一般而論,既“忘”,忘掉一切,就不可能再尋覓、相見並採取、運升和運用了。但在內丹修煉中,二者卻能協同運演,並產生良好的功效。
《合宗明道集》的《小周天河車綱領論》引沖虛日:“當機在吸,則順吸機而升乾。升不降非全不降,以滅闔辟,乃不重於降,而專重於升,只見升不見降也。當機在呼,則順呼機而降坤,降不升非全不升,但其升若無,而專重於降,只見降不見升也。此乃周天先後二氣消息之機也。”
升同降是兩個對抗的意念,一般而論,在同一時限內,意既在升就不能降,意既在降,就不可能升。但在丹功修持中卻可以讓二者協同運演,以適應內外氣的升降規律。
所以會出現上述這種情況,這是由於丹功修煉到一定階段的獨特需要。
就寂與照的協同運演來說,丹功在實現了凝神入氣穴之後,便要固守丹田進行溫養,以便孕育、催化、集聚真氣。這時除要保持並深化虛靜心態之外,還要通過微弱的心理運演,以促進內丹的形成。
所謂“寂而照,照而寂”,正是在這樣的情況下出現的。此時,主體既要用無念之念來儘量弱化自我意識,又要輕輕運用神光和目力激惹丹田部位,以引發內在氣機。因為只有依靠寂靜的心態,“照”才得以進行,才能夠對丹田發揮激惹作用;而神光、目力的默默下照丹田,又可以促進心態的進一步虛靜。二者是相反而相成的。“寂而又寂,照而複照”,神的品位便不斷提升,真氣也就不斷激發出來了。
就忘與覓等的協同運演來說,內丹功在采藥結丹過程中,一方面要運用“忘”字訣,同時又要進行覓、見、采等心理作為。
不斷進行主動性遺忘,是為了保持虛靜的心態,而金丹的基礎真精,也只能在虛靜的心態中去覓,去見,去采,即所謂“恍惚之中尋有象,杳冥之內覓真精”《悟真篇》。
王沐說:“稱恍惚,稱杏冥,均闡明此基礎之物並非有形有質,乃氣氤氳於五臟百骸之中,講尋、講覓,即指出必須以神為體,以意為用,從似有如無之中取而煉之。”
所以說,此時修煉既要在恍恍惚惚之中尋覓,又要在尋覓中恍恍惚惚,絕不可顧此失彼。要儘量讓兩個對抗的意念緊密配合,相互依存。這樣,才能取得良好的效果。
就升與降的協同運演來說,當人體深吸氣時,吸氣肌收縮,胸部外擴,腹部鼓起,外部呈上升態勢,但此時膈肌下降;當人體深呼氣時,吸氣肌舒張,腹部凹陷,外部呈下降態勢,但此時膈肌上升。古人將人體呼吸時膈肌的升降和腹肌的張縮及其對丹田、經脈的激惹作用,稱作內呼吸或先天之氣。這樣外內呼吸便出現了這樣的關係:吸氣時後天之氣升,但先天之氣降;呼氣時後天之氣降,但先天之氣升。
《金仙證論》說:“外面之氣降,裡面之氣則過我而升;外面之氣升,則裡面之氣過我而降。”《道竅談》說:“以內息踵外息,以外息踵內息,以息息踵息息。”說的都是這種內外呼吸的升降關係。古人說:“人之呼出,則氣樞外轉而辟;吸入,則氣樞內轉而闔,是氣之常度也。”
這是就外呼吸而言。古人又說:“天根闔辟,猶人之呼吸也。呼則接天根,是謂辟也;吸則接地根,是謂闔也。”
這是就內呼吸而言。這樣外內呼吸又出現了這樣的關係:當呼氣時,人體內在氣機便處於“開”的態勢;當吸氣時,人體內在氣機便處於“合”的態勢。上面便是人體氣機的升降開合規律。
根據這一規律,周天功運演,在吸氣升乾時,雖然要“專重於升”,但同時又要稍稍留意降,而不是“全不降”;在呼氣降坤時,雖然要“專重於降”,但同時又要輕輕留意升,而不是“只見降不見升”。這樣兼顧升降的協同運演,將大大助於真氣的萌發和真氣的循周天運行。
丹功中兩種對抗意念所以能夠協同運演,有下面幾點原因:
一、因為它僅僅是一種心理運演,心理運演是可以一心兩用的。
二、因為高度虛靜的心態,給相互對抗的意念創造了一個可以互相結合、互相滲透、互相融化的內環境。
三、因為有真意在進行潛在的調控。《青華秘文》說:“意者豈特為媒而已,金丹之道自始至終不可離也。”
所謂真意,其實就是丹功態中表現出來的高度純化、淨化和模糊化的自我意識,是全部作功意念和修持體證的凝縮,它自始至終對功態發揮調控作用。功夫越深,真意的調控功能便越強。
對抗意念的協同運演,符合陰陽和合、陰陽運轉的規律。古人早就指出:“一陰一陽之謂道。”《太平經》說:“天地之性,陽為陰,陰為陽,故陽當變于陰,陰當變于陽。”
《丹經極論》說:“陰陽運轉,皆乾坤之妙用。”因為陰陽二氣是始終不停地在運動變化著的;氣的聚散,就是陰陽的相互推蕩;氣的升降,就是陰陽的相互感召;氣的氤氳,就是陰陽相互揉合。
“若陰陽之氣,則迴圈迭至,聚散相蕩,升降相承,氤氳相揉。蓋相兼相制,欲一之不能。此其所以屈伸無方運行不息,莫或使之。”
宋張載在《正蒙》中說的這段話是很在理的。丹功中的“寂而照,照而寂”,“忘裡覓,覓裡忘”,和“升中降,降中升”等等,正是體現了陰陽和合、陰陽運轉的規律。

氣血到不了的地方就會生病

氣血到不了的地方就會生病

很多人問我,中醫這麼複雜,要怎麼學才不會亂?

其實中醫再怎麼深,我簡單舉例一個比較核心的問題:

氣血到不了的地方,就會生病。

我們先撇開陰陽、經絡、五臟六腑,先來理解,為什麼氣血到不了就會生病。

這像什麼?
就像水灌不到田,田會乾;
陽光照不到的地方,植物長不好;
快遞送不到的家,東西永遠收不到。
人體也是一樣。

哪裡的氣血沒有被送到,那裡就會出問題。

氣血到不了的問題,有時是痛、有時是腫、有時是麻、有時是掉髮、變黑、發癢、發炎、長東西、長不出來。

氣血到不了的問題
有時是痛,像是頭痛、胃痛、關節痛、經痛、胸口悶痛;

有時是麻,多見手麻腳麻、半邊麻木、走久了腳底發麻;

有時是掉髮,髮為血之餘,氣血不到頭皮,頭髮自然易斷、易落;

有時是變黑,像黑眼圈、唇色發暗、眼眶或手指關節發黑;

有時是發癢,皮膚局部癢、搔抓不癒、濕疹反覆;

有時是發炎,氣血運行不暢,局部鬱熱上升,紅腫熱痛;

有時是長東西,像痘痘、囊腫、瘤塊、肌瘤、乳頭分泌物;

有時是長不出來,該排的不排、月經來不順、汗出不出、毒素積在體內。

那為什麼氣血會到不了?
其實原因只有兩種,真的只有兩種。

一、送不出來──身體沒力氣送
這種情況不是堵住,是根本沒有力氣,或沒東西可以送。

氣虛——推不動,快遞車沒油了。
血虛——沒內容物,倉庫空了。
會讓人覺得:累、懶、手腳冰、頭暈、心悸、健忘、月經量少,甚至傷口不好、皮膚乾癢。

像這種情況的處理原則是補氣養血,把系統重新開起來。
不只是給它吃的,還要讓它動得起來。
但注意:這種情況如果同時又有「堵住」,那補進去也沒用,會更壓、會更堵。
—
二、送不過去──路被擋住了
有些人不是沒力氣,是路上太多障礙物。
你有氣有血,但送不出去,一樣沒用。
這種「堵住」,這就涉及很多層面的問題了:
因為氣滯:
情緒壓著、悶著、撐著,氣走不動,身體就悶、脹、痛。
常見在胸悶、肋痛、脹氣、經前不舒服、乳房脹痛。
那就需要:疏肝理氣,打開氣機的開關。
—
因為血瘀:
氣推不動,血就堵。或者你原本就有瘀傷、瘤、血塊卡在裡面。
常見症狀:刺痛、有定點的痛、暗紅、瘀青、經血有血塊。
那就需要:活血化瘀,慢慢把淤堵清掉。
—
因為痰濕:
吃太好、動太少、脾太弱,水濕留在體內變成濁氣、痰飲、濕毒。
你會覺得重、脹、脹得不明顯、咳痰、舌苔厚膩、頭昏。
那就需要:健脾化濕、化痰導滯,把路上的爛泥清掉。
—
因為寒邪:
怕冷、吹風、吃冰,寒氣進來讓整個經絡「凍住」。
會痛得很緊、很深、怕碰,手腳冰冷,關節僵硬。
那需要:溫陽散寒,讓身體回暖、讓路打開。
—
因為熱邪:
火氣太大、虛火上升、熬夜、壓力爆炸,氣血亂竄、方向錯了。
常見:口破、痘痘、失眠、便祕、心煩、兩頰熱。
必須:清熱疏導,把火氣引下來,讓氣血歸位。

你看,其實不複雜。
不管是虛(送不出),還是實(送不過),
只要氣血沒送到,身體就會出狀況。
—
這就是中醫在看病的重點——不是哪個臟腑有問題,而是哪裡沒顧到,生病了。

我們做的事也不是「塞更多東西進去」,而是去思考一個很簡單但很重要的問題:「氣血要怎麼回得來?」

必須這樣子去思考,也代表你正走在中醫的路上了。

利用類神經網路智慧型控制晶片實現之聲控電梯

本公司自從2019年開始利用系統單晶片(System-On-Chip, SoC)進行開發、測試、與實驗各種語音聲控平台至今,在各種不同平台來實現智慧型控制系統。特別在於離線作業的環境,例如封閉的工廠、車間、或是深山野外,乃至於我們常用的電梯環境,如今,我們採用人工智慧類神經網路(Neural Network)控制晶片能直接運用在商業行為、工業製造、以及人類的生活裡,除了豐富人們的生活,更可帶來便利,以及實現無障礙環境、弱勢人群緊急服務、以及創造人類更寬廣的空間與未來!!

聲控電梯,我們的第一步!!

由本公司自行研發的「智慧型聲控電梯控制系統」,此系統可以透過各種介面,包括傳統電梯的乾接點或數位傳輸訊號方式進行樓層控制、開關門、叫車功能、乃至於緊急呼叫等功能。

此外,此套系統還可以客製化各種不同應用場景,例如醫院、酒店、智慧住宅、商場、學校。。。等等,以及可以依據不同國家、地理位置、或環境,提供不同回話口音,包括標準國語、臺灣國語、北京國語、或是英語、日語等等。未來將可擴及方言。

此系統發想於如何讓身心障礙者、婦女或老人、提重物時的辛勤工作者、或其他不便於操作電梯時,可以不用尷尬地請人幫忙,透過此套語音識別技術讓語音辨識能力達到97%以上的辨識度,而語音回覆更可依據業者要求進行客製化修改,包括語調、回覆詞、以及控制程序等。

此外,此系統還可依據不同場景進行客製化。例如酒店飯店業,每個樓層給予特定命名,可分層介紹該樓層的特色,讓服務更能貼近人性。

本公司專注於嵌入式系統、系統單晶片、以及MCU控制晶片的應用開發,在軟硬體與人工智慧的應用上,讓產品可更接近人們的生活,我們的產品也將帶給弱勢團體、行為障礙人士、或需要幫助的群體,讓智慧生活可以降低這些群體的居住與行為的風險,提升社會對弱勢的多方面照護!!

若需洽詢,可以點擊這裡與我們聯絡!

在Ubuntu 16.04上安裝Postfix+Dovecot+SquirrelMail以及相關設置

Postfix:Postfix是一個免費的開源軟件應用程序,可用作郵件傳輸代理(MTA),用於路由和傳遞電子郵件。提供SMTP服務接收與傳送郵件。

DoveCot: 主要提供POP3與IMAP服務,可提供遠端client連線到郵件伺服器。Dovecot是一個開源MDA(郵件傳遞代理),負責向服務器上的本地收件人郵箱發送電子郵件。Dovecot實現了IMAP(Internet消息訪問協議)和POP3(郵局協議),因此仍然是通過(郵件用戶代理)MUA(如Squirrelmail,Ms Outlook,Thunderbird或Roundcube)訪問電子郵件的不錯選擇。

SquirrelMail:是一套提供網頁電子郵件(WebMail)服務。

1. 安裝網頁伺服器(Apache2 + php + letsEncrypt SSL)

$ sudo apt-get update
$ sudo apt-get install apache2
$ sudo apt-get install php libapache2-mod-php
$ sudo apt-get install software-properties-common python-software-properties
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-apache
$ sudo certbot --apache -d example.com 

安裝letsencrypt SSL 系統將提示您輸入電子郵件地址以進行緊急SSL續訂和緊急通知。 輸入地址,然後按Enter鍵。
接下來,按A並按Enter鍵以同意條款和條件。
如果您想與Electronic Frontier分享您的電子郵件,請按Y並按Enter鍵,否則按N並按Enter鍵。
在SSL安裝結束時,系統會詢問您是否要重定向流量,只需為沒有重定向選擇1並按Enter鍵

你最後應該得到一個祝賀信息:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2018-11-04. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

2. 安裝Postfix

$ sudo apt-get install postfix

執行此安裝指令後,會出現下面畫面,按下TAB到OK,然後按下enter繼續:

下面畫面選擇Internet Site:

下面畫面輸入電子郵件所在的網域:

3. 設定Postfix:

我們將對postfix配置文件進行一些更改。 我們將備份原始文件並創建一個新的配置文件,而不是編輯文件/etc/postfix/main.cf:

$ sudo mv /etc/postfix/main.cf /etc/postfix/main.cf.bk
$ sudo nano /etc/postfix/main.cf

下面是設定的範例:

smtpd_banner = $myhostname ESMTP $mail_name
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no
readme_directory = no

#SMTP CONFIGURATION
smtp_use_tls=yes
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# SMTPD CONFIGURATIONS
# SMTPD AUTHENTICATION

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth


# SMPTD TLS

smtpd_use_tls=yes
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

smtpd_tls_cert_file=/etc/letsencrypt/live/example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/example.com/privkey.pem

myhostname = mail.example.com
myorigin = /etc/mailname
mydestination =  localhost.$mydomain, localhost
relayhost = 
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

此設定並未採用virtual mailbox,若此伺服器提供多個mail server服務,則需採用virtual mailbox。

4. 安裝與設定Dovebot:

接下來,我們將安裝Dovecot以及IMAP,POP和LTMPD所需的所有軟件包。 後者使用本地郵件傳輸協議(LMTP)將電子郵件傳遞到本地收件箱。

當電子郵件發送到我們的服務器時,Postfix會將其傳遞給Dovecot以進行本地傳遞。 此外,我們的電子郵件客戶端SquirrelMail將通過Dovecot通過IMAP協議從本地存儲中檢索電子郵件。

$ sudo apt-get install dovecot-core dovecot-imapd dovecot-pop3d

啟用 IMAP / POP3 登入
修改 /etc/dovecot/conf.d/10-auth.conf,我們的SSL將採用letsencrypt的SSL證書,他是免費又好用的SSL。

一般使用者的發送 Email 的流程,不是 Webmail 就是用 SMTP。這裡 SMTP 清晰一點是 SMTP Submission,即是 MUA 透過 MSA 委托 MTA 代為傳送郵件 (Relay)。而 SMTP Submission 當然需要有登入設定,不然肯定會成為 Spam Mail 的 Open Relay了。現在的 Postfix 預設設定已經不允許 Open Relay,所以必需先設定登入機制才能外部使用。

Postfix 使用模組化的設計,各部分都是分開的。換句話說您可以使用很多不同的登入插件,SASL (Simple Authentication and Security Layer) 就提供 Postfix 和 登入插件間的溝通。

Postfix 目前支援 Cyrus 和 Dovecot 的 SASL 實作。本部分是為了將 SMTP 的 MSA 登入驗證整合到 Dovecot。
啟用 SMTP Submission Port 587
目前很多 ISP 封鎖了 Port 25 的連線,所以要改用協議中定義的 Port 587 來收件。修改 /etc/postfix/master.cf,把這一行 Uncomment 就好了。

submission inet n       -       -       -       -       smtpd

Dovecot SASL / Postfix 整合
啟用 Dovecot 內建的 SASL,修改 /etc/dovecot/conf.d/10-master.conf
Uncomment “#Postfix smtp-auth” 下面一段,並加入 user 及 group。

service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Its default
  # permissions make it readable only by root, but you may need to relax these
  # permissions. Users that have access to this socket are able to get a list
  # of all usernames and get results of everyone's userdb lookups.
  unix_listener auth-userdb {
    #mode = 0600
    #user =
    #group =
  }
 
  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postdrop
  }
 
  # Auth process is run as this user.
  #user = $default_internal_user
}

Dovecot 建議只在 SMTP Submission (Port 587) 啟用 SASL 驗證,
原因是當 Dovecot SASL 不可用時,也不至於連收信都失敗。
我們就按指引完成:

修改 /etc/postfix/master.cf,把之前指定在 main.cf 的設定都搬過來,並指定 SASL Socket Path

submission inet n       -       -       -       -       smtpd
 -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination,reject_authenticated_sender_login_mismatch
 -o smtpd_sasl_local_domain=$myhostname
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_sasl_security_options=noanonymous
 -o smtpd_sasl_type=dovecot
 -o smtpd_sasl_path=private/auth
 -o broken_sasl_auth_clients=yes

這個 master.cf 的格式 非常嚴格:
= 前後都不能有空格
-o 前面必需有空格
每項 Option 的 Value 必不能有空格
不能換行,smtpd_recipient_restrictions 要用逗號隔開
修改完成用 Telnet 測試:

telnet 127.0.0.1 587

如果有出現 220 Response 的話,恭喜中獎了

220 server.tiger-workshop-mail.com ESMTP Postfix

若沒有,則查看/var/log/mail.log,看看問題在哪裡。
若成功了,執行ehlo local就會看到下面的敘述:

telnet localhost 587
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.dubugroup.com ESMTP Postfix (Ubuntu)
ehlo localhost
250-mail.dubugroup.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN
250-AUTH=PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

若看到下面兩個,代表可以驗證成功了!!

250-AUTH PLAIN
250-AUTH=PLAIN

透過外部 SMTP 發送成功了,Email 當然還帶有前面設定過的 SPF 和 DKIM。

到了這裏,只要設定 Dovecot 的 User,
SMTP、IMAP、POP3 都會使用同一個 Username & Password,
而且收信地址也會跟 Username 一樣,實在太美好了…

Ubuntu 其實有提供一個 Package “dovecot-postfix” 整合套件,直接完成以上的東西。
這跟 Windows 下的 XAMPP 和手動安裝 Apache, MySQL, PHP 然後手動整合一樣,
手動設定會學到比較多原理,Debug 比較容易吧。

最後安裝SquirrelMail網頁郵件:
接下來我們可以配置SquirrelMail客戶端。 該應用程序是通過SMTP和IMAP協議發送和接收電子郵件的理想選擇,可以在任何瀏覽器上運行。

要安裝該軟件,請運行以下命令:

$ sudo apt-get install squirrelmail

照著指示依序安裝後即可。
接下來,我們將把SquirrelMail路徑添加到Apache的默認虛擬主機文件中,該文件啟用了LetsEncrypt的加密SSL證書。

$ sudo nano /etc/apache2/sites-enabled/000-default-le-ssl.conf

在ServerName後面加上Alias設置,Alias /mail /usr/share/squirrelmail

<VirtualHost *:443>
... 
ServerName example.com
Alias /mail /usr/share/squirrelmail
...
</VirtualHost>

接著設置SquirrelMail就很簡單了

$domain = 'example.com';
$imapServerAddress = 'example.com';
$imapPort=993;  
$smtpPort=465; 
$smtp_auth_mech='login';
$use_imap_tls='true';
$use_smpt_tls='true';

修改/etc/access

用來允許或拒絕RELAY的網域,可參考 這裡。設定後,執行下面的指令才可轉換為access.db

 postmap hash:/etc/postfix/access

設定別名(Alias)

作為群組發信的很重要的應用,例如:[email protected],這個sales是個團隊,將發送到sales可轉發給其他特定的人員,其詳細說明可參考這裡。執行下面的指令才可轉換aliases.db

postalias hash:/etc/aliases

 

MongoDB 3.4 Sharding 觀念、安裝、與配置

Sharding 為 MongoDB 所擁有的一種資料分散處理架構,簡單的說就是將資料分片 (Shard) 儲存到不同的機器中,最常應用在大數據的案例上。在海量資料的儲存情境上,垂直擴充架構是無法滿足的,必須透過水平擴充來實現。

MongoDB Sharded Cluster 基本的架構示意如下:

在這樣的機制下,儲存進 Collection 的資料會被盡可能平均地分散到每一個 Shard 上,每一個 Shard 都是由獨立的 mongod 實體或者 Replica Set 所構成 (想了解 Replica Set 可以看看之前的文章)。上圖我們也可以看到,Sharding 機制本身是不負責備份的,在產品上線的環境中,強烈建議使用 Replica Set 來搭建 MongoDB Sharded Cluster。在這個架構中,假設我們有 1TB 的資料,可以透過 Sharding 機制將資料切分為四個 Shard,每一個 Shard 負責儲存 256G,應該很好理解。

MongoDB Sharded Cluster 運作機制

那麼 MongoDB Sharded Cluster 是如何運作的呢?我們先看看下面的架構圖:

當使用者或應用程式 (Driver) 要操作 MongoDB Sharded Cluster 時,是透過 mongos 來進行連接,mongos 扮演 Router 的角色,Router 通常由多個實體組成,可以將 Loading 分散處理,保持高可用性 (HA)。對於應用程式來說,並不需要瞭解 MongoDB Sharding 怎麼運作的,他們看到的只是一個資料庫,所以使用上基本不會有太大的差別。如下所示:

之前提到,雖然每一個 Shard 都是由一個 mongod 或 Replica Set 構成,但如果沒有透過 mongos (Router) 進行連線操作,而直接對 Shard 進行連線,那麼你看到 Collection 的資料就不會是完整的集合,而只是單一個 Shard 的資料。那麼 Cluster 是如何分配資料呢,這裡有一個很重要的角色,就是 Config Server。

Config Server

Config Server 是 MongoDB Sharding 架構中相當重要的一個角色,它存放了資料的 Metadata,包括透過 Shard Key 計算出來的索引,用來記錄每一個資料存放的 Shard 位置,好讓 Router 可以正確的 Query 資料,如果沒有這些索引,那麼每一個用來存放資料的 mongod 實體,就「純粹」只是獨立存放分散的資料,無法協同工作。Config Server 聽起來很重要對吧!?因此 Config Server 部署時必須要多台機器,在新版 3.2 之後也可以用 Replica Set 架設 Config Server。

為了將資料分散儲存,就必須找一個方法來管理 Index,我們必須將 Document 某一個欄位定義為 Shard Key,然後透過 range based partitioning 或 hash based partitioning 其中一中方式將資料分配到 chunks 中 (每一個 Chunks 預設的大小為 64MB),最後才將 Chunks 分散到不同的 Shard 上。接下來我們先看看兩種不同的 Partitioning 機制:

Range Based Sharding

這種方式就是將 Document Shard Key 欄位的值,以線性的方式進行分群,透過 Range 範圍進行切割,相近的值理所當然會被分到同一個 Chunk 中,Chunk 分配的情況會直接受到 Range 的影響(比如某一段 Range 出現頻率高,Chunk 資料就比較大)。用這種方法我們必須考慮 Shard Key 的範圍,如下所示:

Hash Based Sharding

這種方法顧名思義就是透過「雜湊函式」將我們指定的 Shard Key 欄位進行雜湊,這樣的方式資料比較容易分散到每個 Shard 中,如果資料量足夠豐富,佔用空間的分配也會比較平均。如下:

比較一下兩種方法,Range Based 實際在 Query 時,Router 可以很輕易地判斷資料的位置,然後正確地派送運算到所屬的 Shard 上。但如果要查詢的資料片段大小差異過高,且又分散在不同的 Shard 上,查詢必定會「等待」其他 Shard 處理的情況產生。來看看 Hash Based,Shard Key 透過 Hash 計算後,很容易分散在不同的 Chunk,資料分散性佳,擴充也比較容易。但是在 Query 時就必須要經過比較多的 Shard 計算,才能由 Router 返回最後的結果。兩種方法各有利弊,可以依照實際的應用情況選用。那如果想要自行實作資料分散的邏輯呢?MongoDB 當然也是支援的,就是透過 Tag 這個功能,但我沒有研究,所以就無從介紹了。有興趣可以看看官方 Tag Aware Sharding 相關介紹。

開始建置:

由於 Shard 本身沒有備援機制,因此 MongoDB 的 Shard 必須建置在 Replica Set 上,Replica Set 建置方式請參考「MongoDB Replica Set 高可用性架構搭建」這一篇文章。假設您已經建立好 Replica Set,那麼就可以繼續接著開始建置 Shard。

我們規劃原來做的mongsh1~mongsh3三台伺服器,都拿來做shard server與config server,另外mongsh1/mongsh2拿來當router。

建置 Config Server

一開始我們先建立 Config Server,在 MongoDB Sharding Cluster 架構中,Config Server 必須有三個實體以上,強烈建議部署在不同的機器上,因為 Metadata 實在太重要了。下面的範例其實是與 Replica Set 一起部署,實際上分開會比較好。慣例上我們會先透過 /etc/hosts 管理我們的主機資訊 (用 DNS 也是可以),假設要安裝 Config Server 的 Hostname 為 mong-cfg1 ~ mong-cfg3

vi /etc/hosts
10.21.1.45 mongsh1
10.21.1.46 mongsh2
10.21.1.44 mongsh3

10.21.1.45 mong-cfg1
10.21.1.46 mong-cfg2
10.21.1.44 mong-cfg3

10.21.1.45 mong-router1
10.21.1.46 mong-router2

接著建立 Config Server 要存放的 DB File Directory,命令如下:

mkdir -p /home/mongodb-cfg
sudo chown -R mongodb:mongodb /home/mongodb-cfg

三台伺服器都要做。

然後建立 MongoDB Config Server 需要的設定檔,之後再透過 mongod 來載入啟用,因為我們測試環境的 Config Server 與 Replica Set 都在其實同一台機器(正式環境建議分開或分散比較好),Port 與 PID 都要不同,Port 隔開可以方便我們部署在不同機器,然而透過不同的設定檔也會比較好進行管理。大致上的 Port 分配如下:

  • Replica Set:27019 Port
  • Config Server:27018 Port
  • Mongo Router (mongos):27017 Port

編輯 Config Server 設定檔內容如下:

vi /etc/mongod-cfgserv.conf
storage:
  dbPath: /home/mongodb-cfg
  journal:
    enabled: true
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod-cfgserv.log
sharding:
   clusterRole: configsvr
net:
  port: 27018
  bindIp: 0.0.0.0
processManagement:
  fork: true
  pidFilePath: /var/run/mongod-cfgserv.pid

上面的設定檔先不開啟認證模式,官方規定在 Production 環境最少要配置三台以上的 Config Server。透過以下 mongod 命令分別在「mong-cfg1, mong-cfg2, mong-cfg3」三台機器各別透過 mongod 指令來啟用 Config Server。

sudo mongod -f /etc/mongod-cfgserv.conf

啟動後我們也可以在 /var/log/mongodb/mongod-cfgserv.log 看到 log 資訊。

建置 MongoDB Router

再來就是建置 MongoDB Sharding Router。首先建立 mongos 要載入的設定檔,基本上跟上面 Config Server 使用的 mongod 差不多。我們這裡測試用的 Router 是跟 Config Server 放在一起,實際上可分開存放會更好。

這裡,我們就都不設定認證模式,若有意設置,可參考這篇文章。

設定檔內容如下:

sudo vi /etc/mongod-router.conf
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod-router.log
sharding:
  configDB: mong-cfg1:27018,mong-cfg2:27018,mongodb-cfg-3:27018
net:
  port: 27017
  bindIp: 0.0.0.0 
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb-router.pid

我們可以看到上述的設定檔有指定 Config Server 的位置,好讓 Router 啟動時可以讀取 Config Server 中的 Metadata。也需要配置到另外一台伺服器mong-router2

如同上述的設定檔,先不用啟用認證來執行 mongos,主要是為了要先在 Config Server 中建立 User 好讓後續整個認證流程可以順利串起來,這裡通常大家都會遇到最多問題,很多人最後乾脆關閉認證來配置 Sharding,這樣其實很危險,不建議關閉認證。此外由於應用程式大多是透過 27017 Port 進行連線,所以要提供連線的 Router Bind 直接啟動在標準 MongoDB Port 這樣應用程式就不用修改囉。

先啟用其中一台的 MongoDB Sharding Router,等透過 Mongo Router 設定好 Config Server 之後再啟動所有的 Rouer 即可。注意這裡是用 mongos 命令來啟動喔,如下:

sudo mongos -f /etc/mongod-router.conf

配置自動啟動config與router服務:
於10.21.1.45與10.21.1.46兩台伺服器

vi /etc/rc.local
mongod -f /etc/mongod-cfgserv.conf
mongos -f /etc/mongod-router.conf

於10.21.1.44則配置如下

vi /etc/rc.local
mongod -f /etc/mongod-cfgserv.conf

建立 Sharding Cluster

接著我們透過認證模式進入 Mongo Router 來設定 Sharding,因為後端的 Monogd 是採用Replica Set 認證模式,所以配置 Sharding 的動作一定要透過同一把 Key 啟動,才能把服務整個串起來。以下透過我們建立好的管理者帳密登入 Mongo Router 來進行配置:

mongo mongodb-router1
mongos>sh.addShard("bes/mongodb-a1:27019,mongodb-a2:27019,mongodb-a3:27019")

加入後,再檢查一下狀態:

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
	"_id" : 1,
	"minCompatibleVersion" : 5,
	"currentVersion" : 6,
	"clusterId" : ObjectId("59b4e7b564bf31ba36e4615c")
}
  shards:
	{  "_id" : "bes",  "host" : "bes/mongsh1:27019,mongsh2:27019,mongsh3:27019",  "state" : 1 }
  active mongoses:
	"3.4.8" : 2
 autosplit:
	Currently enabled: yes
  balancer:
	Currently enabled:  yes
	Currently running:  no
		Balancer lock taken at Sun Sep 10 2017 20:27:09 GMT+0800 (CST) by ConfigServer:Balancer
	Failed balancer rounds in last 5 attempts:  5
	Last reported error:  Cannot accept sharding commands if not started with --shardsvr
	Time of Reported error:  Wed Sep 13 2017 11:18:59 GMT+0800 (CST)
	Migration Results for the last 24 hours: 
		No recent migrations
  databases:
	{  "_id" : "teammerge12",  "primary" : "bes",  "partitioned" : true }

mongos> 

實務的配置上,我們會部署多台 Router 來平衡應用程式端的查詢,在應用程式中也可以指定這一群「Router」作為 Server。到這裡 MongoDB Sharding Cluster 就算是被置完成囉,實際的使用上還需要指定 Collection Shard Key 來分配 Chunk 到不同的 Shard 上,這裡請自行參考 MongoDB 官方的 Shard Key 使用介紹。