• 2013-07-17

    使用 jemalloc 编译过程出错的问题

    Views: 16269 | No Comments

    使用 jemalloc, 编译过程出现如下报错:

    /usr/include/stdlib.h:589: 错误:‘void* malloc(size_t) throw ()’ 的声明抛出不同的异常
    /usr/include/stdlib.h:592: 错误:‘void* calloc(size_t, size_t) throw ()’ 的声明抛出不同的异常
    /usr/include/stdlib.h:601: 错误:‘void* realloc(void*, size_t) throw ()’ 的声明抛出不同的异常
    /usr/include/stdlib.h:603: 错误:‘void free(void*) throw ()’ 的声明抛出不同的异常
    /usr/include/stdlib.h:617: 错误:‘void* valloc(size_t) throw ()’ 的声明抛出不同的异常
    

    再看 jemalloc 的 manpage, 原来, 是必须在 include jemalloc 之前先 include stdlib.h.

    #include <stdlib.h>
    #include <jemalloc/jemalloc.h>
    
    Posted by ideawu at 2013-07-17 13:54:15
  • 2013-07-02

    SSDB采用了多线程模型

    Views: 25323 | 1 Comment

    自从SSDB 1.5.2版本起, SSDB默认使用了多线程, 将所有写操作放在一个单独的线程中, 这样可以避免写操作阻塞读操作.

    在之前的版本, SSDB的网络模块采用基于epoll IO多路复用的单线程模型, 这种模型非常快速. 不过, 由于LevelDB的特性, 当写操作过快的时候, 合并(Compaction)线程无法及时地完成所有合并, 导致Level-0文件越积越多, 最终强制阻塞所有写操作.

    SSDB新版本采用了多线程模型, 可以避免写操作阻塞读操作. 但是, 因为LevelDB的特性, 写操作仍然可能相互阻塞. 但是, 大部分SSDB的用户不需要担心写操作相互阻塞的问题, 因为大部分的应用的写操作不会那么快.

    可能有读者会提出疑问, 既然多线程这么好, 为什么直到1.5.2版本才采用多线程机制呢? 其实, 在某些情况下, 多线程不一定比单线程程序快. 原来有两个: 一是线程竞争, 二是线程间同步.

    SSDB使用pipe在网络线程和工作线程之间进行通信. 使用pipe, 使得工作线程的结果也是可select的, 这样, 就可以在网络线程中使用select/epoll得查询工作线程, 当工作线程处理完一个任务时, 网络线程能立即将这个结果返回给客户端.

    不过, 经过测试, pipe至少有10us的延迟, 这对于一个高并发的数据库服务器的影响也是可观的.

    不管怎么样, 在牺牲了一点点写性能之后, SSDB的总体可响应能力得到了极大的提高, 在我的机器上仍然能得到20K ops的写速度.

    Posted by ideawu at 2013-07-02 19:30:29
  • 2013-06-28

    nginx-push-stream-module 笔记

    Views: 26088 | No Comments

    nginx-push-stream-module 模块可用于 comet, 服务器向浏览器实时推送消息. 这个模块功能和稳定性还不错, 只是没考虑和外部系统的接口, 所以扩展性比较差. 例如权限验证, 连接的建立和断开等基础信息和外部共享等, 都缺失.

    这里记录几个关键函数, 打算利用 syslog 和外部系统进行信息共享.

    连接建立事件

    ngx_http_push_stream_subscriber_handler();
    

    连接断开事件

    ngx_http_push_stream_cleanup_request_context();
    ngx_http_push_stream_worker_subscriber_cleanup_locked();
    
    Posted by ideawu at 2013-06-28 11:09:46 Tags: ,
  • 2013-06-15

    SSDB 增加了 Compaction 限速功能

    Views: 27874 | 4 Comments

    最新的 SSDB 1.5.0 增加了 Compaction(合并) 限速功能, 避免 LevelDB 在合并的过程中写满磁盘, 导致 SSDB 无法快速的响应请求的情况. 遇到类似问题的 SSDB 用户, 建议你立即升级. 如果你升级之后仍然使用原有的 ssdb.conf 配置文件, 请在 leveldb 一节配置中加入下面一行:

    	compaction_speed: 100
    

    注意缩进. 这表示限速为 100MB/s, 你可以根据你的磁盘性能调整这个数值.

    事实上, 所有使用了 Log-Structured Merge-Tree(LSM-tree) 类似结构的存储服务器, 都可能出现合并过程写满 IO 的问题, 包括 Redis, LevelDB, Cassandra 等. 我不清楚这些软件为什么不加入合并限速功能, 也许是偷懒. 但是, 如果没有合并限速功能, 这些软件的可用性堪忧, 因为它们会出现不确定的几乎无法响应的情况. 我们就曾经忍受了 Redis 合并带来的业务频繁报警, 最后不得不禁用其自动合并功能, 改为在凌晨手动(crontab)触发合并.

    据我所知, 新浪微博使用的 Redis 也是他们自己加上了合并限速模块.

    SSDB 项目地址: https://github.com/ideawu/ssdb

    Posted by ideawu at 2013-06-15 14:14:32 Tags:
  • 2013-05-06

    LevelDB 写操作出现停顿的问题分析

    Views: 33351 | 4 Comments

    我写了一个简单的循环程序往 LevelDB 写数据进行测试, 发现偶尔会出现停顿的情况, 单个写操作可能会耗时超过1秒. 这种慢请求是非常致命的, 因为在高并发的 Web 应用中, 1秒钟影响到的用户是成百上千个.

    经过分析, 发现 LevelDB 实现了写限速机制, 当 Level-0 的 sst 文件数超过一定数量时开始限速, 再超过一定数量时, 直接主动的阻塞写操作, 直到 Compaction 线程减少了 Level-0 的 sst 文件数量减少到阀值以下.

    Continue reading »

    Posted by ideawu at 2013-05-06 13:51:55 Tags: ,
  • 2013-05-02

    C/C++ 语言 switch-case 后面的花括号

    Views: 18015 | 1 Comment

    C/C++ 语言的 switch-case 语句中常见下面两种风格的代码, 一种在 case 后面加了花括号, 而另一种不加. 这似乎仅仅是编程风格的不同, 但事实上, 两种写法有作用域方面的考虑.

    // style A
    switch(c){
        case 1:
            //
            break;
    }
    
    // style B
    switch(c){
        case 1:
            {
                //
            }
            break;
    }
    

    Continue reading »

    Posted by ideawu at 2013-05-02 11:44:35
|<<<34567891011>>>| 7/12 Pages, 71 Results.