今儿看JAVA基础暂时没发现有不会的知识,就不知道该写什么了。
正巧,上周用了几天时间做了MongoDB的研究,把研究结果写一下吧:
MongoDB学习笔记
一、 传统数据库的发展史
1. 传统关系数据库的瓶颈
近10年,网站开始快速发展。火爆的论坛、博客、sns、微博逐渐引领web领域的潮流。对DB的吞吐量、并发的要求逐渐提高。
2. Memcached+MySQL
随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序不再仅仅专注在功能上,同时也在追求性能。程序员们开始大量的使用缓存技术来缓解数据库的压力,优化数据库的结构和索引。
3. Mysql主从读写分离
由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性。Mysql的master-slave模式成为这个时候的网站标配了。
4. 分表分库
随着web2.0的继续高速发展,MySQL主库的写压力开始出现瓶 颈,大量的高并发MySQL应用开始使用InnoDB引擎代替 MyISAM。同时,开始流行使用分表分库来缓解写压力和数据增长的扩展问题。也就在这个时候,MySQL推出了还不太稳定的表分区,这也给技术实力一般的公司带来了希望。
InnoDB和MyISAM区别http://www.cnblogs.com/villion/archive/2009/07/09/1893762.html
5. MySQL的扩展性瓶颈
在互联网,大数据量高并发环境下的MySQL应用开发越来越复杂,也越来越具有技术挑战性。分表分库的规则把握都是需要经验的,分库分表的子库到一定阶段又面临扩展问题。还有就是需求的变更,可能又需要一种新的分库方式。
关系数据库很强大,但是它并不能很好的应付所有的应用场景。MySQL的扩展性差(需要复杂的技术来实现),大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题。
二、 为什么会出现NOSQL
(一)传统的关系数据库在应付超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,例如:
1. Highperformance - 对数据库高并发读写的需求
关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。例如微信、微博。
2. HugeStorage - 对海量数据的高效率存储和访问的需求
对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付。
3. HighScalability && High Availability-对数据库的高可扩展性和高可用性的需求
在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。
(二)在上面提到的“三高”需求面前,关系数据库遇到了难以克服的障碍,而对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地,例如:
1. HugeStorage - 对海量数据的高效率存储和访问的需求
很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高。因此数据库事务管理成了数据库高负载下一个沉重的负担。
2. 数据库的写实时性和读实时性需求
对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说我(JavaEye的robbin)发一条消息之后,过几秒乃至十几秒之后,我的订阅者才看到这条动态是完全可以接受的。
3. 对复杂的SQL查询,特别是多表关联查询的需求
任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品设计角 度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。
(三)因此,关系数据库在这些越来越多的应用场景下显得不那么合适了,为了解决这类问题的非关系数据库应运而生,现在这两年,各种各样非关系数据库,特别是键值数据库(Key-Value Store DB)风起云涌。
目前所知道的的一些开源的NoSQLDB,例如:
Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud,KiokuDB,Scalaris, Kai, ThruDB, ......
这些NoSQL数据库大致可以分为以下的三类:
1. 满足极高读写性能需求的Kye-Value数据库:Redis,TokyoCabinet, Flare
2. 满足海量存储需求和访问的面向文档的数据库:MongoDB,CouchDB
3. 满足高可扩展性和可用性的面向分布式计算的数据库:Cassandra,Voldemort
三、 关系型数据库和非关系型数据库的对比
从编程,性能,扩展性都可以进行对比:
1. 编程
对于程序员来说,非关系型数据不需要掌握复杂的sql语句,大多采用键值对和api获取数据。而关系型数据库需要使用标准sql,并且有索引,分组,约束等等问题需要注意。
2. 性能
非关系型数据库由于不是关联表结构,并且数据的存储方式与关系型数据也有很大不同,因此在检索和写入的过程中减少了很多约束条件的检测,极大的提升了读写速度。比传统数据快3-5倍,数据参考http://www.oschina.net/question/23734_10930。
千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。写入性能同样很令人满意,同样写入百万级别的数据,基本10分钟以下可以解决。
3. 扩展性
mongodb采用内存映射和分片制度,并且每个分片采取多各个备份。数据更容易存放在多个内存段,可以用一台服务器,也可以多台服务器,对环境要求很小。另外,mongodb允许不同结构的文档数据存放在同一张表中,对表结构要求很小,数据可以随意存储
总结:
并不是说nosql用于了诸多优点就可以取代传统关系型数据库。在复杂业务需求和严格的验系统约束下,要求准确性,安全性更高的场景里面,我们更多选用的传统关系型数据库。
四、 MongoDB简介
MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似 json的bjson格式(二者的区别参照博文http://www.cnblogs.com/zeliliu/archive/2012/10/01/2708330.html),因此可以存储比较复杂的数据类型。
Mongo主要解决的是海量数据的访问效率问题,根据官方的文档,当数据量达到50GB以上的时候,Mongo的数据库访问速度是MySQL的 10倍以上。Mongo的并发读写效率不是特别出色,根据官方提供的性能测试表明,大约每秒可以处理0.5万-1.5次读写请求。
由于Mongo可以支持复杂的数据结构,而且带有强大的数据查询功能,因此非常受到欢迎,很多项目都考虑用MongoDB来替代MySQL来实现不是特别复杂的Web应用。
五、 你说了这么多,太虚了,我就想知道什么时候用MongoDB。
说到这里,我不得比提到关系型数据库和非关系型数据库了。
天明老师不才,查找了很多资料,各路大神众说纷纭;再加上在我在DB方面的造诣太弱,所以还是把自己觉得不错的文章推荐给大家,让大家自己领悟吧
推荐一下两篇文章:
1、Mysql与MongoDB的区别:
http://blog.sina.com.cn/s/blog_966e430001019s8v.html
2、对比MySQL,你究竟在什么时候更需要MongoDB:
http://www.csdn.net/article/2014-03-06/2818652-when-use-mongodb-rather-mysql
3、MySQLvs.MongoDB 各有胜负!
http://www.csdn.net/article/2012-09-06/2809618-mysql-vs-mongodb-complete
六、 安装
1. 官方的下载地址:http://www.mongodb.org/downloads。
2. 这里要选择最新的版本(我下载的版本号为:mongodb-linux-x86_64-2.6.1),一定要选64位的文件,因为32位的mongoDB最大只能支持2.5G的数据。
3. 接着,我把它放到了linux系统的 opt文件夹下
4. 运行命令
5. 解压后,因为文件夹名字太长,可以考虑改一下名字,方便后面修改环境变量
6. 接着我们进入文件夹,主要注意这两个可执行文件,
服务启动命令mongod
客户端命令mongo
7. mongoDB默认的数据库文件会建立在/data/db下。如果需要自定义location,需要启动服务里配置相应参数。
我们需要手动创建/data/db,并创建log文件 启动服务
无用户验证模式
--logpath是选择打log的位置,--logappend是追加日志,--fork是守护进程。如果想通过守护进程的方式启动,则必须配置—logpath。
Mongod的详细启动配置参照网址:http://blog.sina.com.cn/s/blog_5c45656c010120wx.html
9. 启动服务
查看进程发现,mongo默认占用的端口为27017,建议改掉,防止黑客有针对性的侵入
10. 启动客户端
11. 将到这里,安装的步骤已经都讲完了。当然涉及到服务启动的命令还会有一些知识需要说一下,我会随着下一章mongo命令把这块的知识带出来。
12. 主从模式
这里可以考虑做主从复制,mongoDB的主从的实现非常简单:
>mongod --dbpath=xxxx--port=8888--slave--source=127.0.0.1:27017
xxxx为slave服务放置DB数据的地方。
8888为slave服务的接口。
127.0.0.1:27017为master的地址:端口
七、 MongoDB有以下需要注意
1. 由于mongodb不支持事务操作,所以事务要求严格的系统(如果银行系统)肯定不能用它。
2. 数据安全性问题,mongoDB默认的情况是将数据写入缓存中,则标志位成功,但是当缓存flush到硬盘这个过程中失败了的话,就会出现数据丢失的问题。因此,当需要保证数据的安全性的时候,需要使用getLastError。
3. 删除锁定问题,当批量删除记录时,数据库还是会锁定不让读写。这意味着进行数据清理时会让网站应用失去响应。
4. 内存占用问题,MongoDB用了操作系统的内存文件映射,这导致操作系统会把所有空闲内存都分配给MongoDB,当MongoDB有这个 需要时。更可怕的是,MongoDB从来不主动释放已经霸占的内存,它只会滚雪球一样越滚越大,除非重启数据库。
以上,自己也做了个小例子,有需要的同学可以找我来索取。