• 2013-04-02

    LevelDB 会丢数据吗?

    Views: 34589 | 14 Comments

    Google 公司开源的 LevelDB KV 存储引擎是一个非常不错的东西, 支持 zset 数据结构的 SSDB 存储服务器便是使用 LevelDB 作为存储引擎. SSDB 的目的是用来替代 Redis, 作为大数据量存储的服务器. 为什么要在 LevelDB 上面做封装呢? 因为传统的 KV 存储天生不适合存储集合数据, 但实际业务几乎都要求处理集合数据.

    LevelDB 将数据写到磁盘上以保证持久化, 但一个重要的问题是, LevelDB 会丢数据吗? 如果程序意外退出, 或者机器掉电, LevelDB 的数据会丢失吗? 其实, 包括 Redis 在内, 甚至是所有的关系数据库系统, 也会面临这个问题.

    LevelDB 的写操作是直接操作文件描述符的, 虽然不是带缓冲的标准 IO 的 FILE, 看起来数据会被立即写到磁盘上, 但这个"立即"所对应的时间可就长了.

    首先, write() 函数返回时, 数据可能并未到达磁盘, 甚至到达了磁盘也可能只存在于磁盘的可丢失缓冲区. 当然, 如果数据确实达到了磁盘, 丢失的机率就非常小了. 数据何时被写到磁盘, 一般由操作系统内核控制. Linux 内核默认需要 30 秒才将数据刷新到磁盘上. 30 秒可是很长的时间! 丢失的数据可能达到几十万条.

    而 LevelDB 使用了 mmap, 这个时间可能更长!

    我给 LevelDB 提了一个 issue, 希望能给加上一个类似 Redis 的 sync everysecond 机制, 起一个单独的线程, 每隔一秒将数据刷到磁盘. 不过, 开发者认为这个线程不应该被加入到 LevelDB 里, 而是应该由使用者自己来实现.

    一些有用的讨论: http://oldblog.antirez.com/post/redis-persistence-demystified.html

    Posted by ideawu at 2013-04-02 20:30:23 Tags:
  • 2013-03-22

    SSDB数据库的大规模应用

    Views: 30358 | 13 Comments

    SSDB是一个开源的高性能数据库服务器, 使用Google LevelDB作为存储引擎, 支持T级别的数据, 同时支持类似Redis中的zset和hash等数据结构, 在同时需求高性能和大数据的条件下, 作为Redis的替代方案.

    分布式

    因为SSDB的最初目的是替代Redis, 所以SSDB会经常和Redis进行比较. 我们知道, Redis是经常的"主-从"架构, 虽然可以得到负载均衡以及数据跨地域备份的功能, 但无法实现高可用性. 考虑这种情况, Redis的主和从分别在两个IDC机房, 当主所在的机房出现故障时, 整个服务其实就相当于停止了. 因为所有写操作都失败, 而应用一般不会实现自动降级服务.

    而SSDB支持"双主"架构(SSDB分布式架构: https://github.com/ideawu/ssdb/wiki/Replication), 两个或者更多的主服务器. 当其中一部分出现故障时, 剩余的主服务器仍然能正常接受写请求, 从而保证服务正常可用, 再将DNS解析修改之后, 就能在机房故障后立即恢复100%可用.

    实际应用

    SSDB最先在"IT牛人博客聚合网站"进行尝试应用, 接着在360游戏部门得到大规模应用, 目前支撑的数据量已经达到数百G. 这些应用最初使用Redis, 迁移到SSDB的成本非常低, 涉及的代码改动极小.

    你可以拿SSDB的PHP API文档Redis的PHP API文档进行对比.

    SSDB开源数据库项目地址: https://github.com/ideawu/ssdb

    Posted by ideawu at 2013-03-22 11:26:09 Tags: ,
  • 2013-03-08

    SSDB存储服务器的最近进展

    Views: 23739 | 6 Comments

    春节期间的半个多月, 因为我休假, 所以SSDB没有任何更新. 但是, 我们生产环境中的SSDB实例是一直在跑着的, 数据量每天都增加千万条. 服务器一直运行稳定, 不需要任何维护工作.

    上周, 在经历一次机房网络故障之后, SSDB的主从同步出现了问题, 同步复制中断了. 在这次故障中, SSDB Master的心跳机制(noop包)检测到了网络故障, 然后关闭了socket. 但是, 由于之前并没有实现Slave的心跳机制, 所以Slave一直阻塞在了socket的read操作上. 再加上socket没有开启keepalive(即使开启了keepalive, TCP也要过2小时才开始发送keepalive包), Slave就一直阻塞住了.

    这个故障说明SSDB的监控工具需要尽早开发了. 当然, 这个问题现在已经解决, 就是实现了Slave的心跳机制. 当Slave在一段时间后没有收到Master的消息, 就会主动断开重连.

    目前, SSDB的主从同步机制还需要进一步完善. 虽然Master的同步日志队列已经加大到了1000万条更新操作, 但对于上百G数据的完全同步的成本还是非常大, 所以需要一种diff-patch或者类似rsync的机制.

    注: SSDB是一个LevelDB的网络服务器, 用C/C++编写, 支持zset/map/list等数据结构. SSDB是开源的, 项目主页在 https://github.com/ideawu/ssdb.

    Posted by ideawu at 2013-03-08 16:10:45 Tags:
  • 2013-01-28

    SSDB增加hlist, zlist命令

    Views: 26180 | 4 Comments

    最近一段时间以来, SSDB 一直保持的稳定的更新速度, 代码在完善, 功能在丰富和整合. 目前已经有多个国内和国外用户在尝试使用, 相信很快就可以成为 SSDB 的正式用户.

    前几个版本, SSDB 增加了 log rotate 功能. 最新的更新版本中增加了 hlist 和 zlist 命令, 用于列出当前的 map 和 zset. KV 结构的数据仍然使用 keys 列出. *list 既不同于 *keys, 也不同于 *scan, 因为 *list 用于列出集合的名字, 而后两者则用于列出集合的内容.

    最近 SSDB 在生产环境的使用中, 遇到了多机房的问题. 在机房间网络无法改善的情况下, SSDB 必须能应付这种状况. 这里初步设计了新的同步体系, 欢迎大家一起讨论: https://github.com/ideawu/ssdb/issues/11.

    Posted by ideawu at 2013-01-28 11:24:13 Tags: ,
  • 2013-01-24

    为什么LevelDB用了大量VIRT虚拟内存

    Views: 29747 | No Comments

    在最近的一个项目中, SSDB 刚一重启便使用了 500M 的虚拟内存(top VIRT), 但这都是 LevelDB 使用的, 并不是 SSDB 内存泄露. 在 64 位的环境, LevelDB 会利用 mmap 来读取 sst 文件, 所以导致了大量虚拟内存, 而实际使用的内存 RES 只有 50M.

    在 64 位的环境中, 即使几十 G 的虚拟内存也没有任何影响. 但如果你觉得看起来不好, 可以这样改进:

    • 减少 leveldb::Options 的 max_open_files 参数, 这样 LevelDB 用 mmap 打开的文件就减少了
    • 提供自己定制的 Env, NewRandomAccessFile() 不使用 mmap
    • 改成 32 位环境
    Posted by ideawu at 2013-01-24 11:09:09 Tags: ,
  • 2013-01-23

    SSDB 现在已经支持 Java 语言了!

    Views: 32099 | 16 Comments

    SSDB 现在已经支持 Java 语言了! 先看一个例子:

    SSDB ssdb = new SSDB("127.0.0.1", 8888);
    ssdb.set("a", "123");
    byte[] val = ssdb.get("a");
    

    SSDB Java 的 API 和 PHP, Cpy, Python 等动态脚本语言的 API 有很大不同, 首先 SSDB Java 用异常展示出错, 用 null 或者 Double.NaN 表示 not_found. 另外, 对于列表数据的结果, 返回的是 Response 结构.

    具体使用的时候就知道了, API Doc 地址: http://www.ideawu.com/ssdb/java-doc/

    Posted by ideawu at 2013-01-23 22:45:40 Tags: ,
|<<<123456>>>| 4/6 Pages, 35 Results.