博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据库选择历程

Posted on 2015-12-23 10:32  bw_0927  阅读(586)  评论(0)    收藏  举报

数据库选择历程

我们的项目一直使用MySQL作为数据库. 无论是从C++的服务器, 还是到Golang服务器. 当年搞服务器时, 看大部分人都是用SQL(MySQL/SQLServer), 而Mongo感觉像邪教一样, 再加上服务器还是Linux比较正统, 所以果断选了MySQL.

刚开始感觉,游戏服务器的数据存储其实应该是蛮神圣的过程. 那么多的数据, 需要按照MySQL一样分表, 分字段存储, 为了查询, 还要乖乖的学一下SQL的语法

就这么折腾了几年. 在云DB的蒙蔽下, 一直认为MySQL就是做游戏服务器存储的专业技术. 分布式和存储压力一定交给云DB来做. 直到真正试了下NoSQL在游戏服务器开发里的思路.

用了Golang, 才发现同步写逻辑是多么的优雅.

用了NoSQL系列的数据库, 才意识到: 游戏服务器的数据存储和游戏服务器的存盘两个概念差异其实蛮大的.

MySQL中, 背包其实跟角色完全没有关系, 只是通过1个角色id映射过去, 人为的割裂了数据的关联性. 还硬生生的整出个概念叫结构化查询让你学

NoSQL中, 只是把数据库当成是存储点, 每个角色的数据是完整的一块. 里面怎么存随你便. 每个角色通过id来查询, 其他都没有了

于是乎, 游戏开发变得异常简单. MySQL角色进门查询4~5次才能搞定要的数据.而NoSQL一口气全查出来, 存盘也无需增量, 直接存盘就可以了

所以现在觉得, NoSQL的思路对于游戏服务器存储来说简直是完美的!

转载请注明: 战魂小筑http://www.cppblog.com/sunicdavy

 

NoSQL数据库方案对比

NoSQL下实现方案很多, 游戏常用的就这么3家: mongo, redis, memcached

下面说下优缺点

mongo

磁盘映射内存数据库

value为document类型, 基于BSON的value序列化

应用场景:

适合多写少读, 例如日志和备份

转载请注明: 战魂小筑http://www.cppblog.com/sunicdavy

 

redis

内存数据库

单核

value限制512M

多种value类型, 游戏用途使用私有的序列化协议(例如protobuf)

支持落地(bgsave)

用户: 新浪, 淘宝, Flickr, Github

应用场景: 适合读写都很高, 数据处理复杂等

转载请注明: 战魂小筑http://www.cppblog.com/sunicdavy

 

memcached

内存数据库

多核

value限制1M

不支持落地(持久化)

用户: LiveJournal、hatena、Facebook、Vox

应用场景: 动态系统中的缓冲, 适合多读少写

转载请注明: 战魂小筑http://www.cppblog.com/sunicdavy

个人评价

memcached 适合网页缓冲, 游戏里很少有使用. 目前只有腾讯云支持云memcached

redis非常适合游戏的内存数据库, 但是落地策略会比较复杂, 需要具体分析, 可以参考后面的链接看下云风怎么处理这个问题

mongo数据库在早期还是非常不错的NoSQL的数据库. 工具比较方便, 可视化. 但是随着近年来游戏的并发度越来越高, 所以为了一次到位, 很多人还是选择了redis

下图参考自知乎问题. 链接在后面有提示, 若侵权请联系删除

转载请注明: 战魂小筑http://www.cppblog.com/sunicdavy

image

参考链接:

    谈谈陌陌争霸在数据库方面踩过的坑( Redis 篇)

http://blog.codingnow.com/2014/03/mmzb_redis.html

转载请注明: 战魂小筑http://www.cppblog.com/sunicdavy

Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析

http://blog.csdn.net/suifeng3051/article/details/23739295

 

http://www.zhihu.com/question/31417262

 

# re: 游戏数据库选型mysql,mongo, redis, memcached[未登录] 2015-07-12 02:11 杨粼波
有redis就用redis,没有就用memcached,memcached是redis的子集,也可以称之为memcached的升级版。redis的查询语句要丰富得多,当然,也是要复杂的多。

mongoDB虽然也是NoSQL数据库,但是与以上两者有很大的区别。首先,它是磁盘数据库,而不是内存数据库,虽然也可以搞成内存数据库,但是那是歪门邪道。而且,该数据库的稳定性有待改进,对于数据库而言,稳定性是我们首要考虑的,服务不能出问题,数据不能出问题。而mysql这样发展了许多年的数据库就是我们的首选了,通常将其作为热备数据库。

redis的热备份看起来很美好,但其实不好用,还有损性能。通常都会被关闭掉。

以前新浪是用的memcached,现在不知道了,他们还好像自己改进了,当然,主要是做分布式。

淘宝也有基于memcached开发的Tair,不过据说现在他们自己也慢慢开始放弃了,主要也是在分布式上作了点文章。http://code.taobao.org/p/tair/src/

对于游戏这样的应用而言,只要不是腾讯那样的用户量级,都不需要考虑分布式的问题。只需要省心便可,用redis功能多,自然是首选。  回复  更多评论 
  

 

# re: 游戏数据库选型mysql,mongo, redis, memcached[未登录] 2015-07-12 02:27 杨粼波
再啰嗦几句。

阿里云也支持memcached的,当然也支持redis,
腾讯云太挫了,我对它印象不好,有用过,redis是今年才支持的,要不是因为不支持redis,我也就不会选择memcached了,很多功能本可以用redis里面很简单一条命令搞定的,不过话说回来,至少也没有它搞不定的事情。

memcached有个最郁闷的事情就是没有什么称手的工具,只有一个php的memAdmin以及http://www.cnblogs.com/xffy1028/archive/2013/02/01/2861706.html

而Redis有一个http://www.oschina.net/p/redisdesktop,这个很好用。

内存数据库相对于磁盘数据库而言,不要抱有太大期望。只不过是说,磁盘数据库随着数据量增大,它的性能会呈指数级降低。而内存数据库基本上是没有太大的影响,仅此而已。磁盘数据库数据量少的时候,可能跟内存数据库的性能差不多哦。  回复  更多评论 
 
 
=============================================================
https://www.zhihu.com/question/19645807
 
对于性能,Redis作者的说法是平均到单个核上的性能,在单条数据不大的情况下Redis更好。为什么这么说呢,理由就是Redis是单线程运行的。
因为是单线程运行,所以和Memcached的多线程相比,整体性能肯定会偏低。
因为是单线程运行,所以IO是串行化的,网络IO和内存IO,因此当单条数据太大时,由于需要等待一个命令的所有IO完成才能进行后续的命令,所以性能会受影响。
而就内存使用上来说,目前Redis结合了tcmalloc和jemalloc两个内存分配器,基本上和Memcached不相伯仲。如果是简单且有规律的key value存储,那么用Redis的hash结构来做,内存使用上会惊人的变小,优势是很明显的。
参考:
《Memcached真的过时了吗?》
《节约内存:Instagram的Redis实践》



mongodb和memcached不是一个范畴内的东西。mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据。mongodb和memcached不存在谁替换谁的问题。

和memcached更为接近的是redis。它们都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存。在我们团队的项目中,一开始用的是memcached,后来用redis替代。

相比memcached:

1、redis具有持久化机制,可以定期将内存中的数据持久化到硬盘上。

2、redis具备binlog功能,可以将所有操作写入日志,当redis出现故障,可依照binlog进行数据恢复。

3、redis支持virtual memory,可以限定内存使用大小,当数据超过阈值,则通过类似LRU的算法把内存中的最不常用数据保存到硬盘的页面文件中。

4、redis原生支持的数据类型更多,使用的想象空间更大。

5、前面有位朋友所提及的一致性哈希,用在redis的sharding中,一般是在负载非常高需要水平扩展时使用。我们还没有用到这方面的功能,一般的项目,单机足够支撑并发了。redis 3.0将推出cluster,功能更加强大。

6、redis更多优点,请移步官方网站查询。
 
 
 
1.mongodb 和memcached不具可比性,一个是基于磁盘的数据库,只是缓存热点数据数据在内存中,一个是全内存cache;
2. memcached支持过期策略,而mongodb仅有一个capped collection(适合存储日志)的策略可以丢弃先存储的历史数据;
3. redis可以做cache,但redis更多是作为内存数据库的角色存在,且一致性哈希的实现还不成熟,如果memcached已经能实现你的需求,没有必要采用不够成熟稳定的redis.


 
 

下面内容来自Redis作者在stackoverflow上的一个回答,对应的问题是《Is memcached a dinosaur in comparison to Redis?》(相比Redis,Memcached真的过时了吗?)

  • You should not care too much about performances. Redis is faster per core with small values, but memcached is able to use multiple cores with a single executable and TCP port without help from the client. Also memcached is faster with big values in the order of 100k. Redis recently improved a lot about big values (unstable branch) but still memcached is faster in this use case. The point here is: nor one or the other will likely going to be your bottleneck for the query-per-second they can deliver.
  • 没有必要过多的关心性能,因为二者的性能都已经足够高了。由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。(比如瓶颈可能会在网卡)
  • You should care about memory usage. For simple key-value pairs memcached is more memory efficient. If you use Redis hashes, Redis is more memory efficient. Depends on the use case.
  • 如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。
  • You should care about persistence and replication, two features only available in Redis. Even if your goal is to build a cache it helps that after an upgrade or a reboot your data are still there.
  • 如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。
  • You should care about the kind of operations you need. In Redis there are a lot of complex operations, even just considering the caching use case, you often can do a lot more in a single operation, without requiring data to be processed client side (a lot of I/O is sometimes needed). This operations are often as fast as plain GET and SET. So if you don’t need just GEt/SET but more complex things Redis can help a lot (think at timeline caching).
  • 当然,最后还得说到你的具体应用需求。Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

来源:Is memcached a dinosaur in comparison to Redis?(其他人的回答同样值得一看)

 

MongoDB一次 I/O 1ms的成绩即便是面对内存级别的Memcached也是很有竞争力的

 

Redis我了解不多,工作中也只是充当“有很多数据结构”的Memcached来使用。。。(Memcached作为数据库一级缓存,Redis作为业务场景二级缓存)
不过据说国外有一些网站的缓存+持久化是完全使用Redis支撑的,可见Redis的特性(丰富数据结构+持久化支持)赋予了它比Memcached更宽泛的使用场景。


mongodb 是文档数据库,用于方便懒人替代mysql等关系数据库的。不过mongodb在内存足够的情况下读写性能不错,大部分应用可以省去cache这一层了。
redis 是分布式的数据结构服务器,功能上覆盖了memcached, 可以代替memcached.
当然memcached也有优势,memcached是多线程的,这样可以充分利用多核能力。redis是单核,要想在那么多数据结构基础上支持多线程,光加锁就会让人疯掉,性能也会下降。
memcache出现比较早,用法也及其简单,get/set/mget, 用来作数据库的缓存真是又方便又快捷,特别是开发的时候,不需要配置,重启既可以数据清零。
redis拿来时还需要改下配置,取消snapshot和log这些持久化方法,而且方法那么多,诱惑人使用各种数据结构了,但是我们知道数据一般是持久化在数据库里,在redis里再来一份,为了维护这俩的一致性,得加不少代码来。所以redis更建议在成形的项目中作为性能优化部件



redis:是算法和数据结构的集合,快速的数据结构操作是他最大的特点,支持数据持久化;3.mongodb是bson结构、介于rdb和nosql之间的,更松散更灵活的,但是不支持事务,只用作非重要数据存储。