2014年11月12日 星期三

[Linux] 使用 awk, sort, uniq, grep, dig 批次驗證 email address @ Ubuntu 14.04

工作時中,偶爾會對 UNIX 系統感動! 雖然有時很簡單的任務會龜毛到硬要連續指令來處理,明明寫一小段 code 就好了啊 Orz

取處已知清單中的 email domain:

$ mysql -e "select email from db.user;" > email.log;
$ sort email.log | uniq | awk -F'@' '{print $2}' | sort | uniq | grep "." > email.domain.log


最後的 grep "." 則是要避開 hostname 不合法的項目(如 localhost 等)。

驗證 mx:

$ dig -t mx test.com +short | wc -l
$ test `dig -t mx test.com +short | wc -l` -ne 0 && echo "ok"


批次驗證:

$ awk '{ system("test `dig -t mx "$1" +short | wc -l` -ne 0 && echo "$1)}' email.domain.log > email.validated.log

2014年11月11日 星期二

[Linux] c++: internal compiler error: Killed (program cc1plus) @ Ubuntu 14.04

最近 編譯 C++ 的 source code 時,開始會蹦出奇怪的狀態:

c++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.

See <file:///usr/share/doc/gcc-4.8/README.Bugs> for instructions.


一開始碰過一兩次後,重開機真的又沒事,但些會開始又常碰到,接著猜想是不是 memory 不夠了,除了用 free -m 觀察外,也把一些 daemon 關掉,真的猜中了 :P

大概是因為我租的機器只有 512MB RAM 啦 Orz

2014年11月8日 星期六

[Linux] 在 UTF8 Terminal 環境下,找尋 Big5 檔案內的關鍵字 @ Ubuntu 14.04

最近想要研究一些老檔案,都是 Big5 編碼,接著就想著到底該怎樣叫 grep 幫你查資料,因為 pattern 要用 Big5 編碼,但 Terminal 是 UTF-8 環境。

我想到的是先把 pattern 轉成 big5 後,透過 xxd 轉乘 hex code,然後一樣將 input 透過 xxd 輸出後用 grep 去找,結果堪用,但不是很方便。

問一下高手,高手獻技:

$ grep -r `echo -ne "大學" | piconv -f utf8 -t big5` target_files

還差一點,因為 Terminal 環境編碼關係,解法:

$ LC_ALL=C grep -r `echo -ne "大學" | piconv -f utf8 -t big5` target_files

此時 Terminal 輸出會亂掉,所以再把 output 從 Big5 轉成 UTF-8:

$ LC_ALL=C grep -r `echo -ne "大學" | piconv -f utf8 -t big5` target_files | piconv -f big5 -t utf8

若想要有 grep highlight ,那就再叫 grep 做一次吧 XD

$ LC_ALL=C grep -r `echo -ne "大學" | piconv -f utf8 -t big5` target_files | piconv -f big5 -t utf8 | grep "大學"

收工!

2014年11月5日 星期三

[Linux] MySQL Server 5.6 更換 DB Location @ Ubuntu 14.04

在 AWS EC2 叫機器出來時,大多都會用 EBS 來擴充空間,對於 mysql server 預設裝在 /var/lib/mysql 時,就容易碰到空間不足的時候。解法:手動更換 mysql db location 吧 :P

順便把 EBS 處理過程也都列一列,假設已經新增並掛載 EBS 空間:

$ sudo lsblk
NAME    MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
...
xvdb    202:16   0     4G  0 disk /mnt
xvdc    202:32   0   500G  0 disk

$ sudo file -s /dev/xvdc
$ sudo mkfs -t ext3 /dev/xvdc
$ sudo mkdir /data
$ sudo mount -t ext3 /dev/xvdc /data
$ sudo chmod 777 /da
$ sudo vim /etc/fstab
/dev/xvdc /data ext3 defaults,nofail 0 2


處理 MySQL Server:

$ sudo apt-get install mysql-server-5.6
$ sudo service mysql stop
$ sudo mv /var/lib/mysql /data/mysql
$ sudo ln -s /data/mysql /var/lib/mysql
$ sudo vim /etc/apparmor.d/usr.sbin.mysqld
  /var/lib/mysql/ r,
  /var/lib/mysql/** rwk,
  /var/log/mysql/ r,
  /var/log/mysql/* rw,

  /data/mysql r,
  /data/mysql** rwk,
  /data/mysql r,
  /data/mysql* rwk,
$ sudo service apparmor restart
$ sudo service mysql start

2014年11月3日 星期一

[Linux] 架設 MongoDB Sharded Cluster 與驗證資料分散性 @ Ubuntu 14.04

今年年初時,把玩過 MongoDB Replica Set ,也試過一些 Map-Reduce 計算等,最近終於又開始抽空實驗了 :P 當時看到不少 Sharded Cluster 搭建在 MongoDB Replica Set 身上,深感 process (server) 的數量不低,就遲遲沒跳下去玩,最近才發現就算只是單一個 MongoDB Server 也可以當作 shared Cluster 一員,就方便啦!

此次 MongoDB Sharded Cluster 架構:
  • 跑兩個 MongoDB Server,分別在 port 10001, 10002
  • 跑一個 MongoDB Config Server - port 20001
  • 跑一個 MongoDB Routing Server - port 30001
以下操作全部都在一台 ubuntu 14.04 server:

$ rm -rf /tmp/mongo && mkdir -p /tmp/mongo/db/1 /tmp/mongo/db/2 /tmp/mongo/db/c /tmp/mongo/log

$ mongod --port 10001 --dbpath /tmp/mongo/db/1 --logpath /tmp/mongo/log/1 &
$ mongod --port 10002 --dbpath /tmp/mongo/db/2 --logpath /tmp/mongo/log/2 &
$ mongod --port 20001 --configsvr --dbpath /tmp/mongo/db/c --logpath /tmp/mongo/log/c &

$ mongos --port 30001 --configdb 127.0.0.1:20001 &


設定 partition 用法:

$ mongo --port 30001
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "version" : 4,
        "minCompatibleVersion" : 4,
        "currentVersion" : 5,
        "clusterId" : ObjectId("###############")
}
  shards:
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
mongos> sh.addShard('127.0.0.1:10001')
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> sh.addShard('127.0.0.1:10002')
{ "shardAdded" : "shard0001", "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "version" : 4,
        "minCompatibleVersion" : 4,
        "currentVersion" : 5,
        "clusterId" : ObjectId("#####################")
}
  shards:
        {  "_id" : "shard0000",  "host" : "127.0.0.1:10001" }
        {  "_id" : "shard0001",  "host" : "127.0.0.1:10002" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
mongos> sh.enableSharding('ydb')
{ "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "version" : 4,
        "minCompatibleVersion" : 4,
        "currentVersion" : 5,
        "clusterId" : ObjectId("######################")
}
  shards:
        {  "_id" : "shard0000",  "host" : "127.0.0.1:10001" }
        {  "_id" : "shard0001",  "host" : "127.0.0.1:10002" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
        {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
        {  "_id" : "ydb",  "partitioned" : true,  "primary" : "shard0000" }
mongos> use ydb
switched to db ydb
mongos> db.ycollection.ensureIndex( { _id : "hashed" } )
{
        "raw" : {
                "127.0.0.1:10001" : {
                        "createdCollectionAutomatically" : true,
                        "numIndexesBefore" : 1,
                        "numIndexesAfter" : 2,
                        "ok" : 1
                }
        },
        "ok" : 1
}
mongos> sh.shardCollection("ydb.ycollection", { "_id": "hashed" } )
{ "collectionsharded" : "ydb.ycollection", "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "version" : 4,
        "minCompatibleVersion" : 4,
        "currentVersion" : 5,
        "clusterId" : ObjectId("#####################")
}
  shards:
        {  "_id" : "shard0000",  "host" : "127.0.0.1:10001" }
        {  "_id" : "shard0001",  "host" : "127.0.0.1:10002" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
        {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
        {  "_id" : "ydb",  "partitioned" : true,  "primary" : "shard0000" }
                ydb.ycollection
                        shard key: { "_id" : "hashed" }
                        chunks:
                                shard0000       2
                                shard0001       2
                        { "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("-4611686018427387902") } on : shard0000 Timestamp(2, 2)
                        { "_id" : NumberLong("-4611686018427387902") } -->> { "_id" : NumberLong(0) } on : shard0000 Timestamp(2, 3)
                        { "_id" : NumberLong(0) } -->> { "_id" : NumberLong("4611686018427387902") } on : shard0001 Timestamp(2, 4)
                        { "_id" : NumberLong("4611686018427387902") } -->> { "_id" : { "$maxKey" : 1 } } on : shard0001 Timestamp(2, 5)


簡易驗證資料分散性:

mongos>

db.ycollection.insert({user:"a", item: "1", rate: 0.3})
db.ycollection.insert({user:"a", item: "3", rate: 0.5})
db.ycollection.insert({user:"a", item: "4", rate: 0.9})
db.ycollection.insert({user:"b", item: "2", rate: 0.1})
db.ycollection.insert({user:"b", item: "3", rate: 0.6})
db.ycollection.insert({user:"b", item: "5", rate: 0.2})
db.ycollection.insert({user:"c", item: "3", rate: 0.2})
db.ycollection.insert({user:"c", item: "4", rate: 0.7})

mongos> db.ycollection.find()
{ "_id" : ObjectId("#################"), "user" : "a", "item" : "3", "rate" : 0.5 }
{ "_id" : ObjectId("#################"), "user" : "a", "item" : "1", "rate" : 0.3 }
{ "_id" : ObjectId("#################"), "user" : "a", "item" : "4", "rate" : 0.9 }
{ "_id" : ObjectId("#################"), "user" : "b", "item" : "2", "rate" : 0.1 }
{ "_id" : ObjectId("#################"), "user" : "b", "item" : "5", "rate" : 0.2 }
{ "_id" : ObjectId("#################"), "user" : "b", "item" : "3", "rate" : 0.6 }
{ "_id" : ObjectId("#################"), "user" : "c", "item" : "3", "rate" : 0.2 }
{ "_id" : ObjectId("#################"), "user" : "c", "item" : "4", "rate" : 0.7 }


接著,想要驗證資料的確是儲存在不同台 mongodb server ,作法就是把資料透過 mongodump 出來(bson),再用 bsondump 印出來驗證:

$ cd /tmp
$ mongodump --port 10001 -d ydb -c ycollection
$ bsondump dump/ydb/ycollection.bson
{ "_id" : ObjectId( "#############" ), "user" : "a", "item" : "1", "rate" : 0.3 }
{ "_id" : ObjectId( "#############" ), "user" : "b", "item" : "2", "rate" : 0.1 }
{ "_id" : ObjectId( "#############" ), "user" : "b", "item" : "3", "rate" : 0.6 }
{ "_id" : ObjectId( "#############" ), "user" : "c", "item" : "4", "rate" : 0.7 }
4 objects found

$ mongodump --port 10002 -d ydb -c ycollection
$ bsondump dump/ydb/ycollection.bson
{ "_id" : ObjectId( "#############" ), "user" : "a", "item" : "3", "rate" : 0.5 }
{ "_id" : ObjectId( "#############" ), "user" : "a", "item" : "4", "rate" : 0.9 }
{ "_id" : ObjectId( "#############" ), "user" : "b", "item" : "5", "rate" : 0.2 }
{ "_id" : ObjectId( "#############" ), "user" : "c", "item" : "3", "rate" : 0.2 }
4 objects found


因此可完成驗證,資料的確分在不同區!有興趣還可以用 MongoDB Aggregate (Map-Reduce) 實作共現矩陣(Co-Occurrence Matrix)及簡易的推薦系統 來驗證 partition 演算法的正確性。