Ubuntu 运行 mongodb 的正确姿势

曾经在多个项目中使用 mongodb,但是最近从头开始安装并启动居然遇到了不少问题。在此记录一下:

环境:Ubuntu 12.04 64bit
版本:mongodb 3.0.2

首先,按照官方教程安装 mongodb。在这个教程中,注意到有一句话

The MongoDB instance stores its data files in /var/lib/mongodb and its log files in /var/log/mongodb by default, and runs using the mongodb user account. You can specify alternate log and data file directories in /etc/mongod.conf.

恩,看来意思是我们可以通过改 /etc/mongod.conf 这个配置文件来设置 data 存放路径。 打开这个文件看看,的确是有这些配置。

# Note: if you run mongodb as a non-root user (recommended) you may
# need to create and set permissions for this directory manually,
# e.g., if the parent directory isn't mutable by the mongodb user.
dbpath=/var/lib/mongodb

#where to log
logpath=/var/log/mongodb/mongod.log

这里假设要用以下命令(称为命令1)启动 mongodb ,指定 wiredTiger 作为存储引擎并标示副本集:

mongod --storageEngine wiredTiger --replSet fbt   # 称为命令1

首先我们非常天真地直接执行上面那行命令:

2015-04-23T14:55:16.152+0800 I STORAGE  [initandlisten] exception in initAndListen: 29 Data directory /data/db not found., terminating
2015-04-23T14:55:16.152+0800 I CONTROL  [initandlisten] dbexit:  rc: 100

Oops,似乎不行,说 /data/db 不存在。这里就是很坑爹的地方了:虽然 mongod.conf 指定了 dbpath,但是实际上这个配置文件没有起作用!而 mongodb 本身认为 /data/db 才是默认路径。毫无疑问,文档在这方面没有写清楚,因此也有别人被坑过。(后来发现,通过 sudo service mongod start 方式启动会默认使用该配置文件)要想让配置生效,必须手动指定配置文件路径,即:

mongod --storageEngine wiredTiger --replSet fbt -f /etc/mongod.conf

不过这里不打算用这种方式。既然没有 /data/db 这个路径,创建一个不就好了?

sudo mkdir -p /data/db

继续执行命令1,继续报错

2015-04-23T15:17:49.274+0800 E NETWORK  [initandlisten] Failed to unlink socket file /tmp/mongodb-27017.sock errno:1 Operation not permitted
2015-04-23T15:17:49.274+0800 I -        [initandlisten] Fatal Assertion 28578
2015-04-23T15:17:49.274+0800 I -        [initandlisten]

***aborting after fassert() failure

既然它删不掉 /tmp/mongodb-27017.sock,那我手动删。删完之后再次执行命令1:

2015-04-23T15:19:44.972+0800 I STORAGE  [initandlisten] exception in initAndListen: 98 Unable to create/open lock file: /data/db/mongod.lock errno:13 Permission denied Is a mongod instance already running?, terminating
2015-04-23T15:19:44.972+0800 I CONTROL  [initandlisten] dbexit:  rc: 100

这个是可以预期的权限问题,因为我们是拿 sudo 创建的 /data/db 文件夹,而执行的时候没有用 sudo。万能的 stackoverflow 告诉我们要这样做:

sudo chown -R `id -u` /data/db

执行之后当前用户就可以在 /data/db 创建文件了。再次执行命令1

fbt@ebs-39239:~/mongodb$ mongod --storageEngine wiredTiger --replSet fbt
2015-04-23T15:29:38.158+0800 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=1G,session_max=20000,eviction=(threads_max=4),statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2015-04-23T15:29:38.264+0800 I CONTROL  [initandlisten] MongoDB starting : pid=30024 port=27017 dbpath=/data/db 64-bit host=ebs-39239
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten]
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten]
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] db version v3.0.2
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] git version: 6201872043ecbbc0a4cc169b5482dcf385fc464f
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1 14 Mar 2012
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] build info: Linux ip-10-111-179-219 3.2.0-36-virtual #57-Ubuntu SMP Tue Jan 8 22:04:49 UTC 2013 x86_64 BOOST_LIB_VERSION=1_49
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2015-04-23T15:29:38.265+0800 I CONTROL  [initandlisten] options: { replication: { replSet: "fbt" }, storage: { engine: "wiredTiger" } }
2015-04-23T15:29:38.334+0800 I REPL     [initandlisten] Did not find local replica set configuration document at startup;  NoMatchingDocument Did not find replica set configuration document in local.system.replset
2015-04-23T15:29:38.351+0800 I NETWORK  [initandlisten] waiting for connections on port 27017

这次终于 OK 了。

如果直接执行,最好是单独开一个 screen。如果不想开 screen,则应当加上 --fork 参数把 mongod放到后台去。我采取开 screen 的方式。退出 screen,执行 ps aux | grep mongo 观察 mongod 是否成功启动:

fbt      29783  0.0  0.0  29476  1676 ?        Ss   14:47   0:00 SCREEN -S mongodb
fbt      30042  3.7  1.7 209004 35496 pts/1    Sl+  15:31   0:00 mongod --storageEngine wiredTiger --replSet fbt
fbt      30059  0.0  0.0  11700   944 pts/0    S+   15:31   0:00 grep --color=auto mongo

可以看到,mongod 已经按照之前给的参数在运行了。

Girl Friends,惑星公主蜥蜴骑士,Touch

谋划已久的一篇文章,忙里偷闲终于能写出来。其实还有好多想写的东西,但是时间不允许。总之先把这篇写了。

要说的是三部漫画里面的几个我认为十分经典的镜头。

首先是《Girl Friends》21话。这一话讲述真理和男朋友分手然后和亚希表白。

我太喜欢最后亚希心理活动的那个描写了,如果要在看过的漫画里选出最佳心理描写,那就是这个了。

心脏砰砰跳的声音,比包厢里的音乐还要大声。
我那时心想,一定是因为我的麦克风开着。

某一次和别人聊天,我把这句话贴过去,说特别好,然后被鄙视说看得太少。聊天的这个人没看过《Girl Friends》,不过这句话仅看文字,也确实非常平淡。那么下面就分析一下到底好在哪。首先是描写有现场感,在画面的基础上,添加了声音的信息,从而让人很容易想象出KTV包间中听到真理表白从而心脏砰砰跳的亚希。最妙的地方在于,这里的心理活动虽然是第一人称的形式,但内容又是以第三人称的方式来叙述的,表达的意思是:你看,虽然我的心脏在砰砰跳,但是我还是很冷静的哦,而且,并不是因为我的心脏跳得太厉害所以声音大,而是因为麦克风开着,对,就是因为麦克风开着导致的。无法压抑激动的亚希,必须以这种方式来强行让自己不要被突如其来的惊喜冲昏头脑,如果只说第一句“心脏砰砰跳的声音,比包厢里的音乐还要大声”,也表达出了亚希很激动这层意思,但是如果没有后面那句,表达效果和深度都差了一大截。森永老师也确实是个天才,什么叫细腻,这就叫细腻。

第二个要说的是水上悟志的小众名作《惑星公主蜥蜴骑士》,不过其实直译的话应该翻作《行星的五月雨》。这部漫画是我看过的所有漫画中,我认为最燃的,没有之一。

本来想分析图的,但是算了,放个属于燃点之一的图吧。

以及之前写的一个短评:

最终战vs亚尼姆斯为何篇幅不够?
看完最终战我还以为漫画是被编辑要求在几话内结束导致剧情被腰斩,但仔细想想不是。为什么打亚尼姆斯草草收场,因为作者心中的最终战是骑士 vs 公主,打亚尼姆斯只不过是个前奏。前奏不能比正片更出彩,否则就不对了。为了放大最后五月雨把手放到夕日手上那一下的燃度/催泪度,必须让对战亚尼姆斯不要太显眼,这就导致了和最强 BOSS 的战斗看起来不太够劲。这是我觉得本作唯一遗憾的地方。

本作一开始感觉比较无聊,但是看了几卷之后就开始停不下来了。水上悟志是个对漫画节奏感有相当好把握的作者。比如他正在连载的的《战国妖狐》,就完美解决了大战之后要怎么从高潮收场的问题:他直接把主角换了。前一半故事里还是反派的人物,在大战之后变成主角,而之前的主角变成反派,而且这个转变还非常自然,并且也没有让故事的节奏突然变慢进入一个索然无味的状态。大战之后故事节奏处理不好的例子实在太多了,比如《东京食尸鬼》就是个失败的典型。当然也有像巨人那种每集都是爆点的漫画,不过大部分漫画节奏都还是有张有弛的,而水上悟志就是节奏掌控的专家。还有一点,水上悟志发便当从不会拖泥带水,不过他发便当的人,也不是随随便便就死的,一般是为了让另外一个人物成长。

说回本作,我觉得百度百科的评价很好“有燃有泪”,看进去的话,本作有不少地方是相当催泪的。我建议在找漫画补的人去看《惑星公主蜥蜴骑士》,这是一部可以让人燃到哭,感动到哭的作品。

最后说最近看完的《Touch》,我想对这部漫画不需要任何介绍。

这张图来自《Touch》第二卷:

这个图说的是浅仓南和上杉和也在餐馆吃(约)饭(会),达也和一个喜欢和也的女生从餐馆旁边走过去。和也和达也互相注意到了,但是两个女生都没发现,然后兄弟二人分别把两个女生的注意力转移开让她们没有发现另一边。看到这里,我就认定《Touch》一定是名作了,虽然之前我也知道。这张图什么意思?达也那边很好解释,因为此时他认为浅仓南是喜欢和也的,所以不想让那个女生去打扰他们。比较复杂的是和也这边,有两种解释:1. 他知道浅仓南喜欢达也,所以不想让她发现达也和另外一个女生走在一起; 2. 在 1 的基础上,和也认为,如果浅仓南发现了,就会很明显地表露出不满,这样会打破自己的希望因为虽然他知道南更喜欢哥哥一些,但是一直没有放弃追求南。另外如果南表露出态度,也会让南比较尴尬,因为她本身是想维持现状的。不管和也的举动要如何解释,这一幕都是相当神的,兄弟两个替对方着想的心情,通过这一幕完美体现了出来。

最后就是漫画史上最经典的表白场景之一:

这个没什么好说的,就是搁在这。
之前我一直不理解为什么浅仓南是国民女神。下面这段话摘自帖子浅仓南在日漫女主角中处于一个什么样的地位?

浅仓南是日本国民偶像。
TOUCH的漫画销量破亿,日本的销量破亿作品总共12部;TOUCH的平均每卷销量380万,仅次于海贼王,略高于灌篮和龙珠,日本的平均每卷销量400万级作品只此4部。
上次动画和特摄男女主角BEST50,浅仓南女性角色票数第一,十岁到六十岁年龄段都是票数前十;十年前朝日电视台全国调查人气动漫角色TOP100,浅仓南总票数第七,女性角色票数还是第一。只要投票面向大众,不局限于低年龄段的死宅,浅仓南轻松秒杀时下那些当红女性角色。

还有些高亮回复:

最喜欢的女主不容玷污
浅仓南给安达充刻画的完美,完美到让人对和也这种输家感到残忍。 很多上虎扑的都把赤木晴子当做心中的女神,但是说实话,仅仅对比人物的话,浅仓南估计能把晴子爆成龙珠中的那巴。

又比如

我会意淫千千万万个女角色,但是其中永远不会有她。

为什么漫画千千万万女性角色中会有这样一个特殊存在呢,只有看了《Touch》才能体会。

P.S. 宾治简直犯规!和也你死得好惨!

ezcf,一个不算失败的作品

4.18 更新
目前 star 数已经达到 55 了,可喜可贺。
主要是因为去 reddit 发了一个帖子。发之前是25个star。之前没有去 reddit 宣传主要是感觉 reddit 门槛太高,geek 比较多,怕被喷。发觉 newsletter 这条路行不通之后,也没别的办法了,reddit 算是不得已的选择。从回复来看,reddit 比我想象的还是要友善不少,是个不错的地方。

这几个月断断续续地完成了一个名叫 ezcf 的库。可以直接 import .py 之外的文件格式,在我看来,还算有趣。所以原本的期望,是在 GitHub 超过 30 个 star,但现在看来,还是预期过高了。国内能宣传的地方差不多宣传了一遍,在 V2EX 发了帖之后,多少吸引了一些人,但是其他社区基本无效。然而真正让我没想到的是去 HackerNews 发帖居然连一个 star 都没增加。说实话,一个开源项目的好坏不取决于代码怎么样,知道的人多,用得人多就是好,这代表有人认同这个东西是有用的,而代码质量啊功能完善度啊都是可以逐渐改善的。没有人用的开源项目没有存在的价值。好在真正去看了项目的人,有几个对我说,“项目非常有趣”,这多少令人欣慰。

上周在推上@了 importpython,他说“pretty cool,下次放进 newsletter”。然而紧接着的 newsletter 里并没有。如果下次还没有,大概就真的没有了。

我感觉 ezcf 没有达到预期认可度的最大问题是,大多人第一眼都不知道它到底在干嘛。如果是列出几个函数的用法,写上输入输出,大家都很明白,问题是 ezcf 并不是这样起作用的,或者说,没法让人第一眼就知道 import ezcf 这句话起了什么作用,以及和之后的 import 语句有什么关系。说实话,一两句话根本说不清楚这个问题。其次是有直接 import 配置文件需求的人并不多。总而言之,没有办法快速展现出项目的有趣之处,这就是问题。

总之先放上地址
https://github.com/laike9m/ezcf
如果不写这篇博客,感觉无法释怀啊。顺便把 README 也放上来好了。

ezcf

Build Status PyPI version Coverage Status

ezcf stands for easy configuration, it allows you to import JSON/YAML/INI/XML like .py files. It is useful whenever you need to read from these formats, especially for reading configuration files.

OK, stop talking, show us some code!

On the left is what you'll normally do, on the right is the ezcf way. Much more elegant isn't it?

Install

pip install ezcf

If you run into error: yaml.h: No such file or directory, don't worry, you can still use ezcf without any problem.

Supported File Types

ezcf supports JSON, YAML, INI and XML with extension json, yaml, yml, ini, xml.

Sample Usage

ezcf supports all kinds of valid import statements, here's an example:

├── subdir
│   ├── __init__.py
│   └── sample_yaml.yaml
├── test_normal.py
└── sample_json.json

Various ways to use configurations in sample_yaml.yaml and sample_json.json:

import ezcf

from subdir.sample_yaml import *
# or
from subdir.sample_yaml import something
# or
import subdir.sample_yaml as sy
print(sy.something)

from sample_json import *
# or
from sample_json import something
# or
import sample_json as sj
print(sj.something)

You can assume they're just regular python files.(Currently ezcf only supports files with utf-8 encoding)

What about relative import? Yes, ezcf supports relative import, as long as you use it correctly.

Something to note before using ezcf:

  1. ezcf is still in developement. If you find any bug, please report it in issues;
  2. Be careful importing YAML which contains multiple documents: if there exists keys with the same name, only one of them will be loaded. So it's better not to use multiple documents;
  3. All values in .ini files are kept as it is and loaded as a string;
  4. Since XML only allows single root, the whole xml will be loaded as one dict with root's name as variable name;
  5. Namespace package is not supported yet, pull requests are welcome.

top