分享人:李航
http://weibo.com/lidaohang
目录介绍
第一章:MongoDB简介及安装

第二章:MongoDB与关系型数据库语法的对比及使用

第三章:MongoDB集群(Replica Set+Sharding)以及经验分享

第四章:MongoDB监控工具及备份策略




                                            2
NoSQL简介
NoSQL(NoSQL = Not Only SQL ),意即反SQL运动,是一项全新的数据库革命性运
动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关
系型的数据存储,相对于目前铺天盖地的关系型数据库运用,这一概念无疑是一种全新
的思维的注入。


 为什么使用NoSQL:
  1. 对数据库高并发读写。
  2. 对海量数据的高效率存储和访问。
  3. 对数据库的高可扩展性和高可用性。
 弱点:
  1. 数据库事务一致性需求
  2. 数据库的写实时性和读实时性需求
  3. 对复杂的SQL查询,特别是多表关联查询的需求                       3
NoSQL四大类
1.key-value存储

                    Tokyo
 Examples           Cabinet/Tyrant, Redis, Voldemort, Ora
                    cle BDB

                    内容缓存,主要用于处理大量数据的高
 典型应用场景
                    访问负载,也用于一些日志系统等等。

                    Key 指向 Value 的键值对,通常用hash
 数据模型
                    table来实现

 强项                 查找速度快

                    数据无结构化,通常只被当作字符串或
 弱项
                    者二进制数据
                                                            4
NoSQL四大类
2.列式数据库


Examples       Cassandra, HBase, Riak

典型应用场景         分布式的文件系统

数据模型           以列簇式存储,将同一列数据存在一起

               查找速度快,可扩展性强,更容易进行
强项
               分布式扩展

弱项             功能相对局限




                                        5
NoSQL四大类
3.文档型数据库

 Examples       CouchDB, MongoDb

                Web应用(与Key-Value类似,Value是
 典型应用场景         结构化的,不同的是数据库能够了解
                Value的内容)

                Key-Value对应的键值对,Value为结构
 数据模型
                化数据

                数据结构要求不严格,表结构可变,不
 强项             需要像关系型数据库一样需要预先定义
                表结构

                查询性能不高,而且缺乏统一的查询语
 弱项                                     6
                法。
NoSQL四大类
4.图结构数据库


Examples       Neo4J, InfoGrid, Infinite Graph

               社交网络,推荐系统等。专注于构建关
典型应用场景
               系图谱

数据模型           图结构

               利用图结构相关算法。比如最短路径寻
强项
               址,N度关系查找等

               很多时候需要对整个图做计算才能得出
弱项             需要的信息,而且这种结构不太好做分
               布式的集群方案。
                                                 7
谁在使用MongoDB




              9
MongoDB简介
1.性能测试图:




注:
1.该测试数据为单台数据节点的测试结果
2. 将Mysql作为最简单的Key-value数据库使用与实际差别较大
3. MongoDB的分片优势在该测试中无法体现出来
4.相对于插入,数据更新性能更能体现出差异,不过未在上图中体现        10
MongoDB简介
2.简介:
Mongo 是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用
于替代传统的关系型数据库或键/值存储方式。MongoDB使用C++开发。不支
持SQL,但有自己功能强大的查询语法。MongoDB使用BSON作为数据存储
和传输的格式。BSON是一种类似JSON的二进制序列化文档,支持嵌套对象
和数组。MongoDB很像MySQL,document对应MySQL的row,collection对
应MySQL的table。
 MySQL term              Mongo term/concept
 database                database
 table                   collection
 index                   index
 row                     BSON document
 column                  BSON field
 join                    embedding and linking
 primary key             _id field
 group by                aggregation
                                                     11
MongoDB简介
3.特点
• 高性能、易部署、易使用,存储数据非常方便。
• 面向集合存储,易存储对象类型的数据。
• 模式自由。
• 支持动态查询。
• 支持完全索引,包含内部对象。
• 支持查询。
• 支持复制和故障恢复。
• 使用高效的二进制数据存储,包括大型对象(如视频等)。
• 自动处理碎片,以支持云计算层次的扩展性
• 支持Python,PHP,Ruby,Java,C,C#,Javascript,Perl及C++语言的驱动程序,
• 社区中也提供了对Erlang 及.NET等平台的驱动程序。
• 文件存储格式为BSON(一种JSON的扩展)
• 可通过网络访问

                                                     12
MongoDB简介
4.功能
• 面向集合的存储:适合存储对象及JSON 形式的数据

• 动态查询:MongoDB 支持丰富的查询表达式。查询指令使用JSON 形式的标记,

 可轻易查询文档中内嵌的对象及数组。

• 完整的索引支持:包括文档内嵌对象及数组。MongoDB 的查询优化器会分析查询表达
 式,并生成一个高效的查询计划。

• 查询监视:MongoDB 包含一系列监视工具用于分析数据库操作的性能。

• 复制及自动故障转移:MongoDB 数据库支持服务器之间的数据复制,支持主-从模式
 及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。

• 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)

• 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加
 额外的机器。                                   13
MongoDB简介
5.适用场合
•   网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需
    的复制及高度伸缩性。

•   缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,
    由Mongo搭建的持久化缓存层可以避免下层的数据源 过载。

•   大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,
    在此之前,很多时候程序员往往会选择传统的文件进行存储。

•   高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路
    线图中已经包含对MapReduce引擎的内置支持。

•   用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及
    查询。

                                          14
MongoDB简介
6.不适用场合
1.高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要
大量原子性复杂事务的应用程序。



2.传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此
类应用,数据仓库可能是更合适的选择。




                                      15
MongoDB简介
        •MongoDB的版本命名规范如:x.y.z;

版本选择
版本选择
        •y为奇数时表示当前版本为开发版,如:1.5.1、1.7.2;
        •y为偶数时表示当前版本为稳定版,如:1.6.3、1.8.2;
        •详情:
         http://www.mongodb.org/display/DOCS/Version+Num
         bers


        •生产环境使用32位机器的数据限制2G,在64位机器
        上坚决要使用64位版本,可以获得更大的内存映射

平台选择    空间,提升MongoDB的性能;
        •至于操作系统,MongoDB是跨平台的,在下载页面
        找自己对应的版本即可;
                                                    16
MongoDB操作
安装
1.Windows平台的安装

 a. 下载地址安装包: http://downloads.mongodb.org/win32/mongodb-win32-
    x86_64-1.8.5.zip
 b. 将其解压到 d:,再重命名为mongo,路径为d:mongo
 c. 在d:盘建一个db 文件夹,路径d:db
 d. d:mongobinmongod.exe --dbpath=c: db --
    logpath=c:mongologsmongodb.log --serviceName MongoDB --install

2.Linux平台安装

 a. 下载地址安装包: http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-
    1.8.5.tgz
 b. 解压mongodb-linux-x86_64-1.8.3.tgz,并重命名(tar zxvf mongodb-linux-
    x86_64-1.8.3.tgz, mv mongodb-linux-x86_64-1.8.3 mongo )
 c. 建立/data/db 的目录, mkdir –p /data/db
 d. /mongo/bin/mongod --dbpath=/data/db/ --logpath=/data/logs/mongodb.log
    --port 27017 --logappend                                            17
MongoDB简介
mongod参数说明
名称               说明
dbpath           数据文件存放路径,每个数据库会在其中创建一个子目录,用于防止同一个
                 实例多次运行的mongod.lock 也保存在此目录中

logpath          日志文件
logappend        日志采用追加模式(默认是覆写模式)
bind_ip          对外服务的绑定ip,一般设置为空,及绑定在本机所有可用ip 上
port             对外服务端口。Web 管理端口在这个port 的基础上+1000
fork             以后台Daemon 形式运行服务
journal          开启日志功能,通过保存操作日志来降低单机故障的恢复时间
syncdelay        系统同步刷新磁盘的时间,单位为秒,默认是60 秒
directoryperdb   每个db 存放在单独的目录中,建议设置该参数
maxConns         最大连接数
repairpath       执行repair 时的临时目录。在如果没有开启journal,异常down 机后重启,
                 必须执行repair操作                               18
MongoDB操作




Database==Database


                     19
MongoDB操作
数据库常用命令
1、Help查看命令提示
  db.help();
2、切换/创建数据库
  use test当创建一个集合的时候会自动创建当前数据库
3、查询所有数据库
  show dbs;
4、删除当前使用数据库
  db.dropDatabase();
5、从指定主机上克隆数据库
  db.cloneDatabase(“127.0.0.1”);
7、修复当前数据库
  db.repairDatabase();
8、查看当前使用的数据库
  db.getName();
9、显示当前db状态
  db.stats();
10、当前db版本
  db.version();
11、查看当前db的链接机器地址
  db.getMongo();
                                   20
MongoDB操作




Collection==Table


                    21
MongoDB操作
Collection集合
1、创建一个聚集集合(table)
    db.createCollection(“collName”);
2、得到指定名称的聚集集合(table)
    db.getCollection("account");
3、得到当前db的所有聚集集合
    db.getCollectionNames();
4、显示当前db所有聚集索引的状态
    db.printCollectionStats();

用户相关
1、添加一个用户
  db.addUser("userName", "pwd123", true); 添加用户、设置密码、是否只读
2、数据库认证、安全模式
  db.auth("userName", "123123");
3、显示当前所有用户
  show users;
4、删除用户
  db.removeUser("userName");

                                                           22
MongoDB操作




Document==Row


                23
MongoDB操作
INSERT
> db.User.save({name:'zhangsan',age:25,sex:true})
> db.User.find()
{ "_id" : ObjectId("4f69e680c9106ee2ec95da66"), "name" : "zhangsan", "age" : 25,
 "sex" : true }
_id组合
ObjectId是"_id"的默认类型。ObjectId使用12字节的存储空间,每个字节二位十六进制数字,
是一个24位的字符串

0 | 1 | 2 | 3 4 | 5 | 6 7 | 8 9 | 10 | 11
时间戳            机器        PID       计数器

1.时间戳:时间不断变化的
2.机器:主机的唯一标识码。通常是机器主机名的散列值,这样可以确保不同主机
  生成不同的ObjectId,不产生冲突。
3.PID:为了确保在同一台机器上并发的多个进程产生的ObjectId是唯一的,
  所以加上进程标识符(PID).
4.计数器:前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId是唯一的。
  后3个字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId也是
  不一样。同一秒最多允许每个进程拥有16 777 216个不同的ObjectId。
                                                                             24
MongoDB操作
Query
1.WHERE
# select * from users where name = 'user1'
> db.users.find({name:"user1"})
{ "_id" : ObjectId("4c4528a0b55f2224d447e4b0"), "name" : "user1", "age" : 21, "sex" : 1}
# select * from users where name = 'user1' and age = 21
> db.users.find({name:"user1", age:21})
{ "_id" : ObjectId("4c4528a0b55f2224d447e4b0"), "name" : "user1", "age" : 21, "sex" : 1}
 2.FIELDS
# select name, age from users where age = 21
> db.users.find({age:21}, {'name':1, 'age':1})
{ "_id" : ObjectId("4c452c343d48c8f284b388e0"), "name" : "user1", "age" : 21 }
# select name, age from users
> db.users.find({}, {'name':1, 'age':1})
3.SORT
# select * from users order by age
> db.users.find().sort({age:1})
# select * from users order by sex asce, age desc
> db.users.find().sort({sex:1, age:-1})


                                                                                           25
MongoDB操作
4.SLICE
# select * from users skip 2 limit 3
> db.users.find().skip(2).limit(3)
Conditional Operators
# select * from users where sex = 1 and age > 23 and age < 28
> db.users.find({sex:1, age:{$gt:23, $lt:28}})
比较操作包括:$gt (>)、$lt (<)、$gte (>=)、$lte(<=)、$ne (!=)
5. IN
# select * from users where age in (23, 26, 32)
> db.users.find({age:{$in:[23,26,32]}})
对应的操作符有 $nin (not in)。
6.COUNT
# select count(*) from users where age > 30
> db.users.find({age:{$gt:30}}).count()
7.OR
# select * from users where age = 25 or age = 28
> db.users.find({$or:[{age:25}, {age:28}]})
# select * from users where age <= 23 or age >= 33
 db.users.find({$or:[{age:{$lte:23}}, {age:{$gte:33}}]})


                                                                26
MongoDB操作
Update
可直接用类似 T-SQL 条件表达式更新,或用 Save() 更新从数据库返回到文档对象。
# update users set age = 100, sex = 0 where name = 'user1‘
> db.users.update({name:"user1"}, {$set:{age:100, sex:0}})
      update() 有几个参数需要注意。
      db.collection.update(criteria, objNew, upsert, mult)
      criteria: 需要被更新的条件表达式
      objNew: 更新表达式
      upsert: 如目标记录不存在,是否插入新文档。
      multi: 是否更新多个文档。
# update users set age = age + 10
> db.users.update({}, {$inc:{age:10}}, false, true)
# update users set age = age + 10, sex = 1 where name = 'user1'
> db.users.update({name:"user1"}, {$inc:{age:10}, $set:{sex:1}})
Remove
remove() 用于删除单个或全部文档,删除后的文档无法恢复。
> id = db.users.findOne({name:"user2"})._id
ObjectId("4c4508818c4a1e0bf570460f")
> db.users.remove(id)
//移除name='use2'的行
> db.users.remove()//移除所有                                        27
MongoDB操作
Distinct
> db.colors.distinct('name')
[ "blue", "green", "orange", "purple", "red", "yellow" ]
Group
#SELECT name, sum(marks) FROM user where name='foo' GROUP BY name
>db.user.group({
key : {‘name’ : true},
cond: {‘name’ : ‘foo’},
reduce: function(obj,prev) { prev.msum += obj.marks; },
initial: {msum : 0}
});
Index
// single ascending
db.colors.ensureIndex({name: 1})
// unique
db.colors.ensureIndex({email: 1}, {unique: true})
// single descending
db.colors.ensureIndex({createdat: -1})
// compound
> db.colors.ensureIndex({name: 1, createdat: -1})
                                                                    28
Similar Data Types




                     29
MongoDB操作
关系型数据库的存储方式:




                    30
MongoDB操作
MongoDB的存储方式:Embedded




                         31
One to Many
>db.news.insert({
 title:'油价上涨,伤不起啊~',
 author:'zhangsan',
 date:'2012-3-21',
 uid:[1,2,3,4]
 tag:["油价","中国","伤不起"]
 });




                                       32
>db.news.insert({
                    One to Many
 "author" : "发改委",
 "body" : "发改委于3月20日上调油价,国内汽柴油价格每吨上调600元!",
 "comments" : [{
     "author" : "犀利哥",
     “body” : “幸亏哥没车,涨吧,涨吧,都来像我这样吧!",
     "date" : "2012-3-20"
   }, {
     "author" : "凤姐",
     "body" : "你妹的,伤不起啊 ~",
     "date" : "2012-3-20"
   }, {
     "author" : "小崔",
     "body" : "尼玛,坑爹啊!刚说话十块钱能买啥?你就上涨油价了~",
     "date" : "2012-3-20"
   }],
 "date" : "2012-3-20",
 "tags" : ["汽油", "油价", "发改委"],
 "title" : "发改委于3月20日上调油价,国内汽柴油价格每吨上调600元!"
 });



                                              33
One to Many




              34
One to Many
例如:
{
    "VendroId": 1,
    "Name": "商家1",
    "ItemInfo": [
      {
        "ItemId": "634422022659939961",
        "ItemName": "商品634422022659939961",
        "ServiceCateId": 1
      },
      {
        "ItemId": "634422022659949961",
        "ItemName": "商品634422022659949961",
        "ServiceCateId": 1
      }
    ],
    "_id": "4de0c71bbeb52e0ecc000001"
}
db.VendorInfo.find({“ItemInfo”:{“$elemMatch”:{"ItemId",
"634422022659949961"}}})
                                                          35
One to Many




              36
Many to Many
>db.sites.insert({domain: 'orderedlist.com'})
>db.sites.insert({domain: 'railstips.org'})
> db.users.insert({
name: 'John',
authorizations: [
ObjectId('4bee280f9e89db4e12bf78e2'),
ObjectId('4bee283c9e89db4e12bf78e3')
]
})
> db.users.insert({
name: 'Steve',
authorizations: [
ObjectId('4bee280f9e89db4e12bf78e2')
]
})
> var orderedlist = db.sites.findOne({domain:'orderedlist.com'})
db.users.find({authorizations:orderedlist._id})
> var railstips = db.sites.findOne({domain:'railstips.org'})
db.users.find({authorizations:railstips._id})
> var john = db.users.findOne({name:'John'})
> db.sites.find({_id:{$in: john.authorizations}})
                                                                   37
Replica Sets复制集
MongoDB 高可用可用分两种:


 Master-Slave 主从复制:
 只需要在某一个服务启动时加上–master 参数,而另一个服务加上–slave 与–
source 参数,即可实现同步。MongoDB 的最新版本已不再推荐此方案。


 Replica Sets复制集:
  MongoDB 在 1.6 版本对开发了新功能replica set,这比之前的replication 功能
要强大一些,增加了故障自动切换和自动修复成员节点,各个DB 之间数据完
全 一致,大大降低了维护成本。auto shard 已经明确说明不支持replication
paris,建议使用replica set,replica set故障切换完全自动。



                                                       38
Replica Sets复制集


           Server-1




Server-2              Server-3




                                 39
Replica Sets复制集
Replica Set 架构是通过一个日志(oplog)来存储写操作的。
oplog.rs 是一个固定长度的 capped collection,它存在于”local”数据库中,用于记
录 Replica Sets 操作日志。

rs1:PRIMARY> db.oplog.rs.find()
{ "ts" : { "t" : 1338459114000, "i" : 1 }, "h" :
NumberLong("5493127699725549585"), "op" : "i","ns" : "test.c1", "o" :
{ "_id" : ObjectId("4fc743e9aea289af709ac6b5"), "age" : 29, "name" :"Tony" } }

ts: 某个操作的时间戳
op: 操作类型,如下:
i: insert
d: delete
u: update
ns: 命名空间,也就是操作的collection name
o: document 的内容

                                                                                 40
分片(sharding)




             Products   Products   Products
Products
 (Shard)


             Products   Products   Products




                                              41
分片(sharding)




[“a”,”f”]   [“f”,”n”]   [“n”,”t”]    [“t”,”{”]
(Shard1)    (Shard2)    (Shard3)    (Shard4)




                                                 42
分片(sharding)


  [“a”,”c”]        [“c”,”n”]           [“n”,”t”]                [“t”,”{”]
  (Shard1)         (Shard2)            (Shard3)                (Shard4)




[“a”,”c”]     [“c”,”n”]        [“n”,”t”]           [“t”,”w”]                [“w”,”{”]
(Shard1)      (Shard2)         (Shard3)            (Shard4)                 (Shard5)


                                                                                    43
分片(sharding)
1.一分片多区间
假设:把shard1的分片划分为二个区间([“a”,”d”],[“d”,“f”]),一个区间
的数据称为块(chunk),把一个块的区间一分为二时,一个块也就变成了二个块。

2.MongoDB的数据分配:当一个块变得越来越大时,MongoDB会自动将其分
割成二个较小的块。如果分片间比例失调,则MongoDB会通过迁移块来确保均衡。
3.块的创建取决你选择的片键(shrad key),片键可以是任意字段和字段的组合。

4.如果存在多个可用的分片,只要块的数量足够多,MongoDB就会把数据迁移到
 其他分片上。这个迁移的过程叫做平衡(balancing),由均衡器(balancer)的进程负
 责执行。
5.文件使用MMAP进行内存映射,会将所有数据文件映射到内存中,但是只是虚
 拟内存,只有访问到这块数据时才会交换到物理内存。如果是读操作,内存中
 的数据起到缓存的作用,如果是写操作,内存还可以把随机的写操作转换成顺
 序的写操作。
6.对每一个块来说,其头部包含了一些块的元数据,比如自己的位置,上一个和下
一个块的位置以及块中第一条和最后一条记录的位置指针。剩下的部分用于存储                44

具体的数据,具体数据之间也是通过双向链接来进行连接。
Replica Sets+Sharding




要构建一个 MongoDB Sharding Cluster,需要三种角色:
•Shard Server: mongod 实例,用于存储实际的数据块。
 使用 Replica Sets,确保每个数据节点都具有备份、自动容错转移、自动恢复能力。
•Config Server: mongod 实例,存储了整个 Cluster Metadata,其中包括 chunk 信息, ,
确保元数据完整性。
•Route Server: mongos 实例,前端路由,客户端由此接入,且让整个集群看上去像单一
进程数据库,多个mongos实现负载平衡,提高客户端接入性能。
Replica Sets+Sharding
集群方案说明:


10.168.136.14   10.168.136.15    10.168.136.16    10.168.136.26     10.168.136.29

Shard1(master) Shard2(master) Shard3(master)      Shard1(slave)     Shard1(arbiter)

Shard2(slave)   Shard3(slave)    Shard1(slave)    Shard3(slave)     Shard2(arbiter)

Shard3(arbiter) Shard1(arbiter) Shard2(arbiter)   Shard2(slave)    Shard3 (arbiter)



Shard1:10.168.136.14,10.168.136.26,10.168.136.16,10.168.136.15,10.168.136.29(arbiter)
Shard2: 10.168.136.15,10.168.136.26,10.168.136.14,10.168.136.16,10.168.136.29(arbiter)
Shard3: 10.168.136.16,10.168.136.26,10.168.136.15,10.168.136.14,10.168.136.29(arbiter)
MongoDB监控及备份
 监控
 1.Mongostat
 2.ServerStatus
 3.mms
 4.Mongolive
 5. collectd


 备份

 1.增量备份fastsync
 2.全量备份mongodump
49
50
Thanks



         Confidential & Proprietary 2010

深入学习Mongo db

  • 1.
  • 2.
  • 3.
    NoSQL简介 NoSQL(NoSQL = NotOnly SQL ),意即反SQL运动,是一项全新的数据库革命性运 动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关 系型的数据存储,相对于目前铺天盖地的关系型数据库运用,这一概念无疑是一种全新 的思维的注入。  为什么使用NoSQL: 1. 对数据库高并发读写。 2. 对海量数据的高效率存储和访问。 3. 对数据库的高可扩展性和高可用性。  弱点: 1. 数据库事务一致性需求 2. 数据库的写实时性和读实时性需求 3. 对复杂的SQL查询,特别是多表关联查询的需求 3
  • 4.
    NoSQL四大类 1.key-value存储 Tokyo Examples Cabinet/Tyrant, Redis, Voldemort, Ora cle BDB 内容缓存,主要用于处理大量数据的高 典型应用场景 访问负载,也用于一些日志系统等等。 Key 指向 Value 的键值对,通常用hash 数据模型 table来实现 强项 查找速度快 数据无结构化,通常只被当作字符串或 弱项 者二进制数据 4
  • 5.
    NoSQL四大类 2.列式数据库 Examples Cassandra, HBase, Riak 典型应用场景 分布式的文件系统 数据模型 以列簇式存储,将同一列数据存在一起 查找速度快,可扩展性强,更容易进行 强项 分布式扩展 弱项 功能相对局限 5
  • 6.
    NoSQL四大类 3.文档型数据库 Examples CouchDB, MongoDb Web应用(与Key-Value类似,Value是 典型应用场景 结构化的,不同的是数据库能够了解 Value的内容) Key-Value对应的键值对,Value为结构 数据模型 化数据 数据结构要求不严格,表结构可变,不 强项 需要像关系型数据库一样需要预先定义 表结构 查询性能不高,而且缺乏统一的查询语 弱项 6 法。
  • 7.
    NoSQL四大类 4.图结构数据库 Examples Neo4J, InfoGrid, Infinite Graph 社交网络,推荐系统等。专注于构建关 典型应用场景 系图谱 数据模型 图结构 利用图结构相关算法。比如最短路径寻 强项 址,N度关系查找等 很多时候需要对整个图做计算才能得出 弱项 需要的信息,而且这种结构不太好做分 布式的集群方案。 7
  • 9.
  • 10.
  • 11.
  • 12.
    MongoDB简介 3.特点 • 高性能、易部署、易使用,存储数据非常方便。 • 面向集合存储,易存储对象类型的数据。 •模式自由。 • 支持动态查询。 • 支持完全索引,包含内部对象。 • 支持查询。 • 支持复制和故障恢复。 • 使用高效的二进制数据存储,包括大型对象(如视频等)。 • 自动处理碎片,以支持云计算层次的扩展性 • 支持Python,PHP,Ruby,Java,C,C#,Javascript,Perl及C++语言的驱动程序, • 社区中也提供了对Erlang 及.NET等平台的驱动程序。 • 文件存储格式为BSON(一种JSON的扩展) • 可通过网络访问 12
  • 13.
    MongoDB简介 4.功能 • 面向集合的存储:适合存储对象及JSON 形式的数据 •动态查询:MongoDB 支持丰富的查询表达式。查询指令使用JSON 形式的标记, 可轻易查询文档中内嵌的对象及数组。 • 完整的索引支持:包括文档内嵌对象及数组。MongoDB 的查询优化器会分析查询表达 式,并生成一个高效的查询计划。 • 查询监视:MongoDB 包含一系列监视工具用于分析数据库操作的性能。 • 复制及自动故障转移:MongoDB 数据库支持服务器之间的数据复制,支持主-从模式 及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。 • 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片) • 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加 额外的机器。 13
  • 14.
    MongoDB简介 5.适用场合 • 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需 的复制及高度伸缩性。 • 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后, 由Mongo搭建的持久化缓存层可以避免下层的数据源 过载。 • 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵, 在此之前,很多时候程序员往往会选择传统的文件进行存储。 • 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路 线图中已经包含对MapReduce引擎的内置支持。 • 用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及 查询。 14
  • 15.
  • 16.
    MongoDB简介 •MongoDB的版本命名规范如:x.y.z; 版本选择 版本选择 •y为奇数时表示当前版本为开发版,如:1.5.1、1.7.2; •y为偶数时表示当前版本为稳定版,如:1.6.3、1.8.2; •详情: http://www.mongodb.org/display/DOCS/Version+Num bers •生产环境使用32位机器的数据限制2G,在64位机器 上坚决要使用64位版本,可以获得更大的内存映射 平台选择 空间,提升MongoDB的性能; •至于操作系统,MongoDB是跨平台的,在下载页面 找自己对应的版本即可; 16
  • 17.
    MongoDB操作 安装 1.Windows平台的安装 a. 下载地址安装包:http://downloads.mongodb.org/win32/mongodb-win32- x86_64-1.8.5.zip b. 将其解压到 d:,再重命名为mongo,路径为d:mongo c. 在d:盘建一个db 文件夹,路径d:db d. d:mongobinmongod.exe --dbpath=c: db -- logpath=c:mongologsmongodb.log --serviceName MongoDB --install 2.Linux平台安装 a. 下载地址安装包: http://fastdl.mongodb.org/linux/mongodb-linux-x86_64- 1.8.5.tgz b. 解压mongodb-linux-x86_64-1.8.3.tgz,并重命名(tar zxvf mongodb-linux- x86_64-1.8.3.tgz, mv mongodb-linux-x86_64-1.8.3 mongo ) c. 建立/data/db 的目录, mkdir –p /data/db d. /mongo/bin/mongod --dbpath=/data/db/ --logpath=/data/logs/mongodb.log --port 27017 --logappend 17
  • 18.
    MongoDB简介 mongod参数说明 名称 说明 dbpath 数据文件存放路径,每个数据库会在其中创建一个子目录,用于防止同一个 实例多次运行的mongod.lock 也保存在此目录中 logpath 日志文件 logappend 日志采用追加模式(默认是覆写模式) bind_ip 对外服务的绑定ip,一般设置为空,及绑定在本机所有可用ip 上 port 对外服务端口。Web 管理端口在这个port 的基础上+1000 fork 以后台Daemon 形式运行服务 journal 开启日志功能,通过保存操作日志来降低单机故障的恢复时间 syncdelay 系统同步刷新磁盘的时间,单位为秒,默认是60 秒 directoryperdb 每个db 存放在单独的目录中,建议设置该参数 maxConns 最大连接数 repairpath 执行repair 时的临时目录。在如果没有开启journal,异常down 机后重启, 必须执行repair操作 18
  • 19.
  • 20.
    MongoDB操作 数据库常用命令 1、Help查看命令提示 db.help(); 2、切换/创建数据库 use test当创建一个集合的时候会自动创建当前数据库 3、查询所有数据库 show dbs; 4、删除当前使用数据库 db.dropDatabase(); 5、从指定主机上克隆数据库 db.cloneDatabase(“127.0.0.1”); 7、修复当前数据库 db.repairDatabase(); 8、查看当前使用的数据库 db.getName(); 9、显示当前db状态 db.stats(); 10、当前db版本 db.version(); 11、查看当前db的链接机器地址 db.getMongo(); 20
  • 21.
  • 22.
    MongoDB操作 Collection集合 1、创建一个聚集集合(table) db.createCollection(“collName”); 2、得到指定名称的聚集集合(table) db.getCollection("account"); 3、得到当前db的所有聚集集合 db.getCollectionNames(); 4、显示当前db所有聚集索引的状态 db.printCollectionStats(); 用户相关 1、添加一个用户 db.addUser("userName", "pwd123", true); 添加用户、设置密码、是否只读 2、数据库认证、安全模式 db.auth("userName", "123123"); 3、显示当前所有用户 show users; 4、删除用户 db.removeUser("userName"); 22
  • 23.
  • 24.
    MongoDB操作 INSERT > db.User.save({name:'zhangsan',age:25,sex:true}) > db.User.find() {"_id" : ObjectId("4f69e680c9106ee2ec95da66"), "name" : "zhangsan", "age" : 25, "sex" : true } _id组合 ObjectId是"_id"的默认类型。ObjectId使用12字节的存储空间,每个字节二位十六进制数字, 是一个24位的字符串 0 | 1 | 2 | 3 4 | 5 | 6 7 | 8 9 | 10 | 11 时间戳 机器 PID 计数器 1.时间戳:时间不断变化的 2.机器:主机的唯一标识码。通常是机器主机名的散列值,这样可以确保不同主机 生成不同的ObjectId,不产生冲突。 3.PID:为了确保在同一台机器上并发的多个进程产生的ObjectId是唯一的, 所以加上进程标识符(PID). 4.计数器:前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId是唯一的。 后3个字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId也是 不一样。同一秒最多允许每个进程拥有16 777 216个不同的ObjectId。 24
  • 25.
    MongoDB操作 Query 1.WHERE # select *from users where name = 'user1' > db.users.find({name:"user1"}) { "_id" : ObjectId("4c4528a0b55f2224d447e4b0"), "name" : "user1", "age" : 21, "sex" : 1} # select * from users where name = 'user1' and age = 21 > db.users.find({name:"user1", age:21}) { "_id" : ObjectId("4c4528a0b55f2224d447e4b0"), "name" : "user1", "age" : 21, "sex" : 1} 2.FIELDS # select name, age from users where age = 21 > db.users.find({age:21}, {'name':1, 'age':1}) { "_id" : ObjectId("4c452c343d48c8f284b388e0"), "name" : "user1", "age" : 21 } # select name, age from users > db.users.find({}, {'name':1, 'age':1}) 3.SORT # select * from users order by age > db.users.find().sort({age:1}) # select * from users order by sex asce, age desc > db.users.find().sort({sex:1, age:-1}) 25
  • 26.
    MongoDB操作 4.SLICE # select *from users skip 2 limit 3 > db.users.find().skip(2).limit(3) Conditional Operators # select * from users where sex = 1 and age > 23 and age < 28 > db.users.find({sex:1, age:{$gt:23, $lt:28}}) 比较操作包括:$gt (>)、$lt (<)、$gte (>=)、$lte(<=)、$ne (!=) 5. IN # select * from users where age in (23, 26, 32) > db.users.find({age:{$in:[23,26,32]}}) 对应的操作符有 $nin (not in)。 6.COUNT # select count(*) from users where age > 30 > db.users.find({age:{$gt:30}}).count() 7.OR # select * from users where age = 25 or age = 28 > db.users.find({$or:[{age:25}, {age:28}]}) # select * from users where age <= 23 or age >= 33  db.users.find({$or:[{age:{$lte:23}}, {age:{$gte:33}}]}) 26
  • 27.
    MongoDB操作 Update 可直接用类似 T-SQL 条件表达式更新,或用Save() 更新从数据库返回到文档对象。 # update users set age = 100, sex = 0 where name = 'user1‘ > db.users.update({name:"user1"}, {$set:{age:100, sex:0}}) update() 有几个参数需要注意。 db.collection.update(criteria, objNew, upsert, mult) criteria: 需要被更新的条件表达式 objNew: 更新表达式 upsert: 如目标记录不存在,是否插入新文档。 multi: 是否更新多个文档。 # update users set age = age + 10 > db.users.update({}, {$inc:{age:10}}, false, true) # update users set age = age + 10, sex = 1 where name = 'user1' > db.users.update({name:"user1"}, {$inc:{age:10}, $set:{sex:1}}) Remove remove() 用于删除单个或全部文档,删除后的文档无法恢复。 > id = db.users.findOne({name:"user2"})._id ObjectId("4c4508818c4a1e0bf570460f") > db.users.remove(id) //移除name='use2'的行 > db.users.remove()//移除所有 27
  • 28.
    MongoDB操作 Distinct > db.colors.distinct('name') [ "blue","green", "orange", "purple", "red", "yellow" ] Group #SELECT name, sum(marks) FROM user where name='foo' GROUP BY name >db.user.group({ key : {‘name’ : true}, cond: {‘name’ : ‘foo’}, reduce: function(obj,prev) { prev.msum += obj.marks; }, initial: {msum : 0} }); Index // single ascending db.colors.ensureIndex({name: 1}) // unique db.colors.ensureIndex({email: 1}, {unique: true}) // single descending db.colors.ensureIndex({createdat: -1}) // compound > db.colors.ensureIndex({name: 1, createdat: -1}) 28
  • 29.
  • 30.
  • 31.
  • 32.
    One to Many >db.news.insert({ title:'油价上涨,伤不起啊~', author:'zhangsan', date:'2012-3-21', uid:[1,2,3,4] tag:["油价","中国","伤不起"] }); 32
  • 33.
    >db.news.insert({ One to Many "author" : "发改委", "body" : "发改委于3月20日上调油价,国内汽柴油价格每吨上调600元!", "comments" : [{ "author" : "犀利哥", “body” : “幸亏哥没车,涨吧,涨吧,都来像我这样吧!", "date" : "2012-3-20" }, { "author" : "凤姐", "body" : "你妹的,伤不起啊 ~", "date" : "2012-3-20" }, { "author" : "小崔", "body" : "尼玛,坑爹啊!刚说话十块钱能买啥?你就上涨油价了~", "date" : "2012-3-20" }], "date" : "2012-3-20", "tags" : ["汽油", "油价", "发改委"], "title" : "发改委于3月20日上调油价,国内汽柴油价格每吨上调600元!" }); 33
  • 34.
  • 35.
    One to Many 例如: { "VendroId": 1, "Name": "商家1", "ItemInfo": [ { "ItemId": "634422022659939961", "ItemName": "商品634422022659939961", "ServiceCateId": 1 }, { "ItemId": "634422022659949961", "ItemName": "商品634422022659949961", "ServiceCateId": 1 } ], "_id": "4de0c71bbeb52e0ecc000001" } db.VendorInfo.find({“ItemInfo”:{“$elemMatch”:{"ItemId", "634422022659949961"}}}) 35
  • 36.
  • 37.
    Many to Many >db.sites.insert({domain:'orderedlist.com'}) >db.sites.insert({domain: 'railstips.org'}) > db.users.insert({ name: 'John', authorizations: [ ObjectId('4bee280f9e89db4e12bf78e2'), ObjectId('4bee283c9e89db4e12bf78e3') ] }) > db.users.insert({ name: 'Steve', authorizations: [ ObjectId('4bee280f9e89db4e12bf78e2') ] }) > var orderedlist = db.sites.findOne({domain:'orderedlist.com'}) db.users.find({authorizations:orderedlist._id}) > var railstips = db.sites.findOne({domain:'railstips.org'}) db.users.find({authorizations:railstips._id}) > var john = db.users.findOne({name:'John'}) > db.sites.find({_id:{$in: john.authorizations}}) 37
  • 38.
    Replica Sets复制集 MongoDB 高可用可用分两种: Master-Slave 主从复制: 只需要在某一个服务启动时加上–master 参数,而另一个服务加上–slave 与– source 参数,即可实现同步。MongoDB 的最新版本已不再推荐此方案。  Replica Sets复制集: MongoDB 在 1.6 版本对开发了新功能replica set,这比之前的replication 功能 要强大一些,增加了故障自动切换和自动修复成员节点,各个DB 之间数据完 全 一致,大大降低了维护成本。auto shard 已经明确说明不支持replication paris,建议使用replica set,replica set故障切换完全自动。 38
  • 39.
    Replica Sets复制集 Server-1 Server-2 Server-3 39
  • 40.
    Replica Sets复制集 Replica Set架构是通过一个日志(oplog)来存储写操作的。 oplog.rs 是一个固定长度的 capped collection,它存在于”local”数据库中,用于记 录 Replica Sets 操作日志。 rs1:PRIMARY> db.oplog.rs.find() { "ts" : { "t" : 1338459114000, "i" : 1 }, "h" : NumberLong("5493127699725549585"), "op" : "i","ns" : "test.c1", "o" : { "_id" : ObjectId("4fc743e9aea289af709ac6b5"), "age" : 29, "name" :"Tony" } } ts: 某个操作的时间戳 op: 操作类型,如下: i: insert d: delete u: update ns: 命名空间,也就是操作的collection name o: document 的内容 40
  • 41.
    分片(sharding) Products Products Products Products (Shard) Products Products Products 41
  • 42.
    分片(sharding) [“a”,”f”] [“f”,”n”] [“n”,”t”] [“t”,”{”] (Shard1) (Shard2) (Shard3) (Shard4) 42
  • 43.
    分片(sharding) [“a”,”c”] [“c”,”n”] [“n”,”t”] [“t”,”{”] (Shard1) (Shard2) (Shard3) (Shard4) [“a”,”c”] [“c”,”n”] [“n”,”t”] [“t”,”w”] [“w”,”{”] (Shard1) (Shard2) (Shard3) (Shard4) (Shard5) 43
  • 44.
    分片(sharding) 1.一分片多区间 假设:把shard1的分片划分为二个区间([“a”,”d”],[“d”,“f”]),一个区间 的数据称为块(chunk),把一个块的区间一分为二时,一个块也就变成了二个块。 2.MongoDB的数据分配:当一个块变得越来越大时,MongoDB会自动将其分 割成二个较小的块。如果分片间比例失调,则MongoDB会通过迁移块来确保均衡。 3.块的创建取决你选择的片键(shrad key),片键可以是任意字段和字段的组合。 4.如果存在多个可用的分片,只要块的数量足够多,MongoDB就会把数据迁移到 其他分片上。这个迁移的过程叫做平衡(balancing),由均衡器(balancer)的进程负 责执行。 5.文件使用MMAP进行内存映射,会将所有数据文件映射到内存中,但是只是虚 拟内存,只有访问到这块数据时才会交换到物理内存。如果是读操作,内存中 的数据起到缓存的作用,如果是写操作,内存还可以把随机的写操作转换成顺 序的写操作。 6.对每一个块来说,其头部包含了一些块的元数据,比如自己的位置,上一个和下 一个块的位置以及块中第一条和最后一条记录的位置指针。剩下的部分用于存储 44 具体的数据,具体数据之间也是通过双向链接来进行连接。
  • 45.
    Replica Sets+Sharding 要构建一个 MongoDBSharding Cluster,需要三种角色: •Shard Server: mongod 实例,用于存储实际的数据块。 使用 Replica Sets,确保每个数据节点都具有备份、自动容错转移、自动恢复能力。 •Config Server: mongod 实例,存储了整个 Cluster Metadata,其中包括 chunk 信息, , 确保元数据完整性。 •Route Server: mongos 实例,前端路由,客户端由此接入,且让整个集群看上去像单一 进程数据库,多个mongos实现负载平衡,提高客户端接入性能。
  • 47.
    Replica Sets+Sharding 集群方案说明: 10.168.136.14 10.168.136.15 10.168.136.16 10.168.136.26 10.168.136.29 Shard1(master) Shard2(master) Shard3(master) Shard1(slave) Shard1(arbiter) Shard2(slave) Shard3(slave) Shard1(slave) Shard3(slave) Shard2(arbiter) Shard3(arbiter) Shard1(arbiter) Shard2(arbiter) Shard2(slave) Shard3 (arbiter) Shard1:10.168.136.14,10.168.136.26,10.168.136.16,10.168.136.15,10.168.136.29(arbiter) Shard2: 10.168.136.15,10.168.136.26,10.168.136.14,10.168.136.16,10.168.136.29(arbiter) Shard3: 10.168.136.16,10.168.136.26,10.168.136.15,10.168.136.14,10.168.136.29(arbiter)
  • 48.
    MongoDB监控及备份  监控 1.Mongostat 2.ServerStatus 3.mms 4.Mongolive 5. collectd  备份 1.增量备份fastsync 2.全量备份mongodump
  • 49.
  • 50.
  • 51.
    Thanks Confidential & Proprietary 2010