• 2013-07-21

    SSDB在大数据量日志分析中的应用案例

    Views: 36638 | 2 Comments

    在一个网站广告系统中, 需要针对每一个用户所接受的弹窗次数和点击次数这两个重要指标进行统计, 从而进行效果分析和精准投放的改进. 这两个指标的统计算法其实非常简单, 主要的难点在于大数据量. 广告系统的涉及的用户量达到数千万人, 每天的日志数据量是几亿条.

    最开始的想法是使用 MySQL 数据库, 不过这个方案马上就被否, 因为如此大量数据已经远远超过 MySQL 的存储能力, 必定带来许多无谓的问题.

    第二个方案是使用 Redis. Redis 是内存存储方案, 速度快, 而且 zset 数据结果存储列表数据非常方便, 能直接地统计用户的弹窗次数和点击次数. 不过, Redis 本身的局限就是它最多能存储不超过内存容量的数据, 对于一台 100G 内存的服务器, Redis 最好是存储不超过 30G 的数据量. 因此, Redis 的方案在运行了短时间之后也被否定了.

    第三个方案是使用 SSDB. SSDB 可以存储 TB(1000GB) 级别的数据, 并且支持列表等集合数据结构, 有着和 Redis 高度兼容的 API, 所以, 当从 Redis 迁移到 SSDB 时, 改动非常小.

    每一个用户的弹窗历史用一个 zset 来存储, key 是时间戳, 对应的 score 也是时间戳, 因为我们只关心用户的弹窗历史, 具体的弹窗信息会用 map 来存储(时间戳作为 key, 对应弹窗信息 value). SSDB 的 zset 支持根据 score 范围来查询, 所以只需要一条命令就能算出用户在任意时间段内的弹窗次数.

    用户的点击统计也是类似.

    Posted by ideawu at 2013-07-21 16:08:46 Tags: ,
  • 2013-07-18

    SSDB 提供了非常详细的 PHP API 文档

    Views: 18568 | No Comments

    以前由于时间的关系, SSDB 的 PHP API 文档比较简单, 几乎就是函数原型的罗列. 现在, 我整理了详细的 API 文档, 做成 HTML 网页, 方便查看.

    地址: http://www.ideawu.com/ssdb/docs/zh_cn/php/

    例如:

    zsize
    
    说明
    
    返回 zset 中的元素个数.
    
    参数
    
        name - zset 的名字.
    
    返回值
    
    出错则返回 false, 否则返回元素的个数, 0 表示不存在 zset(空).
    
    示例
    
    $ssdb->zsize('z');
    

    这份文档已经在 github 代码库中随源码一起发布.

    Posted by ideawu at 2013-07-18 21:21:44
  • 2013-07-17

    用PHP遍历SSDB中的zset集合

    Views: 30697 | 2 Comments

    连接 SSDB

    <?php
    require_once("SSDB.php");
    $ssdb = new SimpleSSDB('127.0.0.1', 8888);
    

    生成测试数据

    $zname = 'test';
    for($i=0; $i<1000; $i++){
        $key = "k$i";
        $score = mt_rand(0, 100);
        $ssdb->zset($zname, $key, $score);
    }
    $size = $ssdb->zsize($zname);
    echo "total $size items\n";
    

    这段代码生成了一个名为 zname 的 zset 集合, 里面有 1000 个元素, 某些元素的权重(score)是相同的.

    Continue reading »

    Posted by ideawu at 2013-07-17 18:55:46 Tags: ,
  • 2013-07-11

    将LevelDB数据导入SSDB

    Views: 23083 | No Comments

    从 1.5.4 版本起, ssdb 提供了 leveldb-import, 用于将已有的 LevelDB 数据导入到 SSDB 中. 这个工具非常简单.

    Usage:
        ./tools/leveldb-import ip port input_folder
    
    Options:
        ip - ssdb server ip address
        port - ssdb server port number
        input_folder - local leveldb folder
    
    Example:
        ./tools/leveldb-import 127.0.0.1 8888 ./leveldb/
    

    为什么需要将LevelDB的数据导入到SSDB? 这是因为, LevelDB仅仅是一个存储引擎, 最直接的使用就是用编译器将这个引擎和你的C/C++代码进行链接. 如果你的需求是需要一个集中存储服务器, 可以从不同的机器上使用 PHP, Python, Java, Lua 等语言进行访问, 那么就需要SSDB了.

    Posted by ideawu at 2013-07-11 11:51:02 Tags:
  • 2013-07-02

    SSDB采用了多线程模型

    Views: 31517 | 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-15

    SSDB 增加了 Compaction 限速功能

    Views: 35416 | 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:
|<<<456789101112>>>| 8/12 Pages, 70 Results.