说说我们组开发的那些key-value存储吧 08月05日

当写下这个题目的时候,很多人会说,哎,又来key-val数据库了,市面上的key-value存储这么多了,为啥还要自己去实现一个?其实最初我也是这样想的,新浪以前不是开发过一个memcachedb么,所有产品线都用就行了呗。后来才弄清楚,原来这个世界上,到目前为止没有像mysql一样的关系数据库垄断key-val数据库是有很多原因的。

先说几个大家熟悉的key-value 解决方案吧,好对比我们的方案。

memcached

memcached不用说了吧,就是传说中的万金油,哪儿痒了点哪里,只要是一个中型网站以上,一般都有memcached的存在。它的好处呢,我觉得太多了,多到没有你不用的理由的地步。在内存这么便宜的年代,memcached 依旧是缓存的最好的解决方案。

但是,它是个cache缓存,也就是不能持久化,当然就不能算作数据库了。但是memcached的作者从来都没有计划把它开发成一个DB,因为cache就是cache嘛,做好这件事情就行了,国外的大神们做的产品,就是专注,不想国内的很多产品经理,一个产品做出来,完全是为了把页面占满。

当然,也有人做了memcached的持久化,这句话有点错,应该是“用memcached的协议,对传入的数据做了持久化”,比如我浪08年开发的memcachedb (更多…)

新型序列化类库MessagePack,比JSON更快、更小的格式 07月26日

新型序列化类库MessagePack,比JSON更快、更小的格式

MessagePack 是个什么东东?先来看一段官方的解释: MessagePack is an effici [...]

bloom filter的开源实现程序memcached bloom filter 11月06日

bloom filter是我目前看到的最经典的算法之一,用非常低的错误率换取非常高的时间、空间的效率,在各种海量数据场景或者需要快速判断的场景中都得到了大量的使用,但是,在国内的互联网,至少公开的研究中,还很少有人把这个当成一个课题来研究,也没有一个系统级别的开源的实现。

mc_bloom_filter 是用memcached的协议来封装的bloom filter的操作,牺牲了一些bloom filter的特性,来成全所有的语言能使用这一高效的工具,这是这个项目开发的目标。 (更多…)

Facebook工程师的MemSQL体验 06月19日

Facebook工程师的MemSQL体验

大早起来,发现微博上全是这个牛逼哄哄的软件的介绍, @刘江CE : 前Facebook工程师创办的MemSQL [...]

在C里面嵌入Lua的过程[lua研究二] 03月09日

偶遇一个事情,需要在C里面嵌入Lua代码,这真是痛苦了我好久….

不知道为啥lua默认编译没有生成.so 的动态链接库,需要修改Makefile生成liblua.so,我用的版本是5.2

一、先修改根目录的 Makefile
修改一行

TO_LIB= liblua.a liblua.so

二、再修改src的Makefile
注意,请搜索关键字,第二行是需要修改的,第一行,和第三行是粘贴的,至于粘贴的位置嘛,你看样子比较像的就粘贴一起吧
第三行的开始是tab键

LUA_SO=liblua.so
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)
$(LUA_SO): $(CORE_O) $(LIB_O)
$(CC) -o $@ -shared $? -ldl -lm

然后编译,安装,ldconfig

make linux
make install

在/etc/ld.so.conf中加入一行
/usr/local/lib/
然后执行
/sbin/ldconfig
重新加载动态链接库。

三、敲两段代码
luadd.c

#include
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

/* the Lua interpreter */
lua_State* L;

int luaadd ( int x, int y )
{
int sum;

/* the function name */
lua_getglobal(L,"add");

/* the first argument */
lua_pushnumber(L, x);

/* the second argument */
lua_pushnumber(L, y);

/* call the function with 2
arguments, return 1 result */
lua_call(L, 2, 1);
//lua_pcall(L, 2, 1,0);

/* get the result */
sum = (int)lua_tointeger(L, -1);
lua_pop(L, 1);

return sum;
}

int main ( int argc, char *argv[] )
{
int sum;

/* initialize Lua */
//L = lua_open();
L = luaL_newstate();

/* load Lua base libraries */
//luaL_openlibs(L);
luaopen_base(L);

/* load the script */
(void)luaL_dofile(L, "add.lua");

/* call the add function */
sum = luaadd( 10, 15 );

/* print the result */
printf( "The sum is %d\n", sum );

/* cleanup Lua */
lua_close(L);

/* pause */
//printf( "Press enter to exit..." );
//getchar();

return 0;
}

lua代码 add.lua

function add(x,y)
return x+y
end

四、当然是gcc了

gcc luadd.c -llua -ldl -g

五、不出意外的话,当然是出现结果

the sum is 25

希望大家这过程顺利

Lua在linux下的安装[Lua研究一] 03月08日


wget http://www.lua.org/ftp/lua-5.2.0.tar.gz
tar zxvf lua-5.2.0.tar.gz
make linux
make install

然后lua就安装好了,简单快捷

print(“a”);

print(“hello”);

Gdb调试多进程程序 02月14日

最近需要调试memcached等程序,发现看代码是一件很悲剧的事情,最后还是借助gdb吧,这个算一劳永逸了。

Gdb调试多进程程序

程序经常使用fork/exec创建多进程程序。多进程程序有自己独立的地址空间,这是多进程调试首要注意的地方。Gdb功能强大,对调试多线程提供很多支持。

方法1:调试多进程最土的办法:attach pid

Attach是调试进程的常用办法,只要有可执行程序以及相应PID,即可工作。当然,为方便调试,可以在进程启动后,设定sleep一段时间,如30s,这样即可有充足的时间来attach。

方法2: set follow-fork-mode child + main断点

当设置set follow-fork-mode child,gdb将在fork之后直接执行子进程,知道碰到断点后停止。如何设置子进程的断点呢?在父进程中是无法知道子进程的地址空间的(只有等程序载入后方可知)。Gdb提供一个很方便的机制:main函数的断点将被子进程继承(毕竟main是任何程序的入口)。

注意:程序在main停下后,可尝试设置断点。断点是否有效,取决于gdb是否已经载入目标程序的地址空间。

方法3: set follow-fork-mode child + catch exec

Cache点是一种特殊的breakpoint。Gdb能够catch的事件很多,如throw/catch/exception/syscall/exec/fork/vfork等。其中和多进程关系最大的就是exec/fork事件。

举例:

GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
(gdb) catch exec
Catchpoint 1 (exec)
(gdb) set follow-fork-mode child
(gdb) r  -d ***
Catchpoint 1 (exec'd /****/binary), 0x0000003c68800a70 in _start ()
from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2
#1  0x0000000000000003 in ?? ()
#2  0x00007fff65c6e85a in ?? ()
#3  0x00007fff65c6e85d in ?? ()
#4  0x00007fff65c6e860 in ?? ()
(gdb) b lib.cc:8720
No symbol table is loaded.  Use the "file" command.
(gdb) c
Continuing
(gdb) bt
#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2
#1  0x0000000000000002 in ?? ()
#2  0x00007fff1af7682a in ?? ()
#3  0x0000000000000000 in ?? ()
(gdb)  b lib.cc:8720
Breakpoint 2 at 0x15f9694: file lib.cc, line 8720.
(gdb) c
Continuing.
[Thread debugging using libthread_db enabled]
[Thread 0x40861940 (LWP 12602) exited]
[Switching to process 12630]
0x0000003c6980d81c in vfork () from /lib64/libpthread.so.0
Warning:
Cannot insert breakpoint 2.
Error accessing memory address 0x15f9694: Input/output error.
(gdb) bt
#0  0x0000003c6980d81c in vfork () from /lib64/libpthread.so.0
#1  0x000000000040c3fb in ?? ()
#2  0x00002adeab604000 in ?? ()
#3  0x01000000004051ef in ?? ()
#4  0x00007fffff4a42f0 in ?? ()
#5  0x686365746e6f6972 in ?? ()
#6  0x0000000d0000000c in ?? ()
#7  0x0000000b0000000a in ?? ()
#8  0x0000000000000000 in ?? ()
(gdb) delete 2  --此处当breakpoint无效时,必须删除,否则程序无法继续
(gdb) c
Continuing.
[New process 12630]
Executing new program: /****/binary
warning: Cannot initialize thread debugging library: generic error
[Switching to process 12630]
Catchpoint 1 (exec'd /****/binary), 0x0000003c68800a70 in _start ()
from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2
#1  0x0000000000000009 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) b lib.cc:8720
Breakpoint 4 at 0x15f9694: file lib.cc, line 8720.
(gdb) b type.cc:32
Breakpoint 5 at 0x1693050: file type.cc, line 32.
(gdb) c
Continuing.
(gdb)  -- 和正常程序调试一样

说明:catch exec后,程序将在fork/vfork/exec处停下。并非每次停下后,设置断点都是有效的。如提供断点无效,需要删除,否则程序无法继续。要能够在新进程中设置断点,一定要等到新进程的地址空间被载入后,设置断点是才有效(exec将改变原程序的地址空间)。上述例子,主要想展示如何对新进程设置断点!

注意:
1)程序地址非常重要(代码和数据地址一样重要)。使用gdb时,多多注意和利用地址信息。
2)On some systems, when a child process is spawned by vfork, you cannot debug the child or parent until an exec call completes.

方法4info inferiors/inferiors inferiors

设置set detach-on-fork off/set follow-exec-mode new

If you choose to set `detach-on-fork’ mode off, then gdb will retain control of all forked processes (including nested forks). You can list the forked processes under the control of gdb by using the info inferiors command, and switch from one fork to another by using the inferior command.

所使用的gdb不支持set detach-on-fork off/set follow-exec-mode new/info inferiors。不清楚。

Nginx模块开发入门【转】 09月19日

Nginx模块开发入门【转】

Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名(根据Alexa)前 [...]

Glibc 内存管理-Ptmalloc2 源代码分析 09月14日

Glibc 内存管理-Ptmalloc2 源代码分析

这篇文章不错,淘宝的一个朋友写的 http://www.heyues.com/book/c/glibc-ptm [...]

使用 libevent 和 libev 提高网络应用性能【转】 09月13日

使用 libevent 和 libev 提高网络应用性能【转】

许多服务器部署(尤其是 web 服务器部署)面对的最大问题之一是必须能够处理大量连接。无论是通过构建基于云的服 [...]