mongodb常用命令可以用在ARM上吗解决思路

MongoDB数据库设计思路 - CNode技术社区
积分: 1030
我总在想如何把蝴蝶训练成最强海军
我的MongoDB设计思路很简单,就是类关系型数据库。操作中大量使用Mongoose的population做关联查询。一直感觉这种设计方式别扭,求教各路大神,如何设计MongoDB?
说明你不会用mongodb,你这样还不如你去用mysql。
nosql换句话说,是以空间换时间
你的确看清了真相,但是能说一下如何设计吗?搜索到的都是大话
你的场景直接用 mysql 有什么不好?
现在回头看确实可以直接用mysql,但是如果就是想用mongodb呢?求mongodb设计方案
为了MongoDB而用MongoDB吗?
做 population 感觉最方便的还是在 mongoose 里面定义关系,然后 mongodb 的表就按 mysql 的范式设计就好了。
是啊,通过population就可以把mongodb设计的和mongoose一样
不是为了用而用,是前人选型已选好了,现在不会做mongodb的设计
我是开发网络游戏的,现在用的是mongodb ,
package 用的mongoose .
设计的时候, 基本上是按照mysql
的思路去设计docoment。
游戏中每一个玩家有唯一的ID :uid , 然后其他的相关的表,都会包括一个uid字段。
userSchema
_id : 使用默认的ObjectId类型
例如关卡表: mission
schema设计如下
{uid : String, missionId : String,
status : Number,
createTime : Number }
这里的uid 就是userSchema 的_id
游戏里面的功能大都是独立的,所以关系性 不是特别强, 用uid 去关联足够了,业务逻辑写起来也非常的简单
我也是这样的设计思路,这样的设计是可以解决问题,只是没有发挥出非关系型数据库的优势。可惜网上只能看到一些说的很宽泛的指导,实际操作会很麻烦。比如看到有人说,所有的数据存在一张集合,简直不能想想如何实操。还有的说,实际上根据mongodb的文档也能看出来,mongodb的设计者也是不提倡使用ref。但是不用ref,如何去设计数据库??这就是我的疑问所在
网游中的金钱事务操作怎么实现的?
用ref关联的话,感觉有点蹩脚,我这边没有用。要说发挥非关系型数据库的优势,mongodb对比mysql的优势不止一点,比如说在数量级别达到一定程度情况下,mongodb比mysql的非索引查询快很多,大量数据的情况下,mongodb比mysql性能要高许多, 这只是说一个优势吧 , 其他肯定还有 。 这就要看 你想要发挥mongodb的哪方面的优势了 。
mysql事务,我的业务里没有用到。基本上都是最简单的CRUD操作,另外写个工具方法,检测下数据的正确性。
这就是捡个东西就当宝的结局
你说的用uid关联是怎么实现的
不是什么时候都有选择机会的
而且node里面用mongodb的确比用mysql查询起来顺手
选择 & 努力
User.where('username', '=', 'xx').fetch().then(function(user) {
console.log(JSON.stringify(user));
User.where('username', '=', 'xxxx')
username: 'oooo',
password: 'xxoo',
}).then(function(res) {
console.log(JSON.stringify(res));
}).catch(function(err) {
console.log(err);
User.where('id', '=', 7)
.destroy()
.then(function(res) {
console.log(res);
.catch(function(err) {
console.log(err);
如果只是查询一些固定的字段,可是试试多做几个冗余字段,,就是维护数据的时候麻烦点,事实上我们这边项目都是这么用的,虽然看上去很low,
就是考虑到一各地方改,其他地方都要改才用了ref
我也是这样的设计思路,这样的设计是可以解决问题,只是没有发挥出非关系型数据库的优势。可惜网上只能看到一些说的很宽泛的指导,实际操作会很麻烦。比如看到有人说,所有的数据存在一张集合,简直不能想想如何实操。还有的说,实际上根据mongodb的文档也能看出来,mongodb的设计者也是不提倡使用ref。但是不用ref,如何去设计数据库??这就是我的疑问所在
userSchema = new mongoose.Schema({
: mongoose.Schema.Types.ObjectId, //默认不需要定义
var userInfo = new userSchema({});
userInfo.save();
//关联
otherSchema = new mongoose.Schema({
: String //指的是userSchema的_id
var otherDocument = new otherSchema({
: userInfo._id
请问有何依据 说这样的对比?
数据量大不大?数据量不大的时候,按最方便编程和理解的方式来做,不要考虑那么多性能和所谓nosql的优势。数据量大的话,详细描述场景和数据结构,我再帮你看看。
2段提交模拟事务,现在在做涉及到金额的操作,写起来很冗长
数据量不大,现在按照关系型数据库设计模式做完全能实现功能,只是心理上有点过不去。因为我用了大量的ref,而mongodb的官方文档对ref的介绍几乎一笔带过,意思就是不鼓励mongodb使用ref。下面是我设计的一个集合,用了四次ref。
var orderSchema = new Schema({
orderNo: {type: String, default: “”},
createTime: {type: Number, default: Date.now},
owner: {type: Number, default: 0,ref:‘User’},
medicineList: {type: Array, default: []},
serviceFee: {type: Number, default: 0},
medicarePaid: {type: Number, default: 0},
totalPrice: {type: Number, default: 0},
totalQuantity: {type: Number, default: 0},
orderState: {type: String, default: ‘待付款’},
logisticsState: {type: String, default: ‘去支付’},
seller: {type: Number, default: 0,ref:‘Hospital’},
consignee_id: {type: Number, default: 0,ref:‘Consignee’},
paymentMode: {type: String, default: ‘’},
signBy: {type: String, default: ‘’},
signTime: {type: Number, default: 0},
courier: {type: Number, default: 0,ref:‘User’},
getPackageWhen: {type: Number, default: 0},
packageReadyWhen: {type: Number, default: 0}
反正你们一开始数据库选型就有问题,就不要纠正美不美的问题啦哈哈
感觉是正解
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的在之前的一篇博文中,已经安装好mongodb与在Ubuntu下运行,调试测试使用c API,现在需要移植到arm平台中,所以有一下笔记,希望对大家有帮助。
有任何错误或者问题希望可以相互交流,我的邮箱:
建议在ARM中编译,就可以避免很多问题。
ARM需要安装:gcc g++ 可以使用apt-get安装
具体步骤可以参照在Ubuntu中的编译方式进行。
1. 编译mongodb,得到mongod与 mongo两个文件。
&& &(这个方法没有试过,记得老大给我的这两个没有strip过是非常大的,两个文件差不多500多M,strip之后20兆左右)
2. 编译mongoc-c-driver
编译后注意查看以下文件:
a. /usr/local/include/下的两个文件:
&& &libbson-1.0& libmongoc-1.0
b. mongo-c-driver-1.6.2/.libs/下的全部库文件
c. mongo-c-driver-1.6.2/src/libbson/.libs/下的全部库文件
&& &如果没有的话就注意看编译的时候是否报错。
将以上文件放到Ubuntu中,修改Makefile库路径,就可以进行交叉编译。
附上Makefile:
SRCS=$(wildcard *.c)
OBJECTS=$(patsubst %.c,%.o,$(SRCS))
CC=arm-linux-gcc
#MYLIBS=-lmongoc-1.0 -lbson-1.0
MYLIBS=-L /home/wzh/workspace/mongo-c-driver-1.6.2/.libs
-lmongoc-1.0
-L /home/wzh/workspace/mongo-c-driver-1.6.2/src/libbson/.libs/
-lbson-1.0
MYINCLUDEPATH= -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0/
$(DEST):$(OBJECTS)
$^ $(MYLIBS)
$^ $(MYINCLUDEPATH)
.PHONY:clean
另外尝试过的方法:
打算再Ubuntu这下交叉编译mongo-c-driver,但是没有成功。
&& &./confirgure ----》ok
&& &想把Makefile中的编译器都变成arm-linux-gcc& arm-linux-g++
&& &make-----》失败,报错。
&& &尝试过几次,查看官方文档支持的平台:
参考链接:http://mongoc.org/libmongoc/current/installing.html
报错处理:
1. ARM平台上运行mongod和mongo出现段错误(Segmentation Fault)
&& &a. 文件格式错误,使用:file命令查看。
&& &&& &readelf -dh mongod 查看运行依赖的库。
&& &b. 文件上传时错误,特别是使用tftp,注意一定要使用二进制传输,bin
&& &c. 可能缺少一些运行的依赖库
2. 运行有输出:大概有个字眼 --dbpath的,说明没有指定数据库路径。需要在运行的时候加上一个参数--dbpath=/data/db(自己定义)
&& &如果还是出现问题,进到/data/db/下,将 ***.lock 文件删除,这是最简单的方法,或者是在运行momgod时添加参数 --repair,然后再运行mongod。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:543次
排名:千里之外1您所在的位置: &
MongoDB集群搭建及Sharding的实现思路
MongoDB集群搭建及Sharding的实现思路
选择一个合适索引而减少索引量,这种索引叫做重复索引,能够在索引中直接查找到所有要查询的索引,叫做覆盖索引,能够满足覆盖索引的条件并且排序次序又能够与索引的次序相同,这种次序是"3星"的,所以任何时候创建索引的目的一定要与搜索码完全匹配,至少保持一致.
MongoDB集群搭建
MongoDB的复制集群类型:
&主从模式(master/slave)
&副本集模式(replica set)
副本及模式至少3个节点(一主二从),从节点负责复制主节点的oplog到本地并且应用到本地从而实现冗余。
(&arbiter:仅参与选举,但不持有任何数据
&0优先级:可以触发选举,但是不能被选举成为主节点
&可以使用repiset来定义集群名称)
1.编译安装MongDB
准备环境:
系统:Debian 7.2 64位
mongodb:mongodb-linux-x86_64-2.4.5.tgz(官网有下)
root@namenode1:/usr/local/tools#&tar&xfmongodb-linux-x86_64-2.4.5.tgz& &root@namenode1:/usr/local/tools#&mv&mongodb-linux-x86_64-2.4.5&/usr/local/ &root@namenode1:/usr/local/tools#&cd&/usr/local/ &root@namenode1:/usr/local#&ln&-s&/usr/local/mongodb-linux-x86_64-2.4.5//usr/local/mongodb &root@namenode1:/usr/local#&ll&|&grep&mongo &lrwxrwxrwx&&1&root&&&staff&&&&38&&3月&17&15:35&mongodb&-/usr/local/mongodb-linux-x86_64-2.4.5/ &drwxr-sr-x&&3&root&&&staff&&4096&&3月&17&15:08&mongodb-linux-x86_64-2.4.5&
root@namenode1:~#&groupadd&-r&mongod &root@namenode1:~#&useradd&-M&-r&-g&mongod&-d&/data/db&-s&/bin/false&-c&mongodmongod&
root@namenode1:~#&mkdir&-p&/var/log/mongo/ &root@namenode1:~#&mkdir&-p&/mongo/data &root@namenode1:~#&chown&mongod&/mongo/data&/var/log/mongo/ &&&root@namenode1:~#&ll&/var/log/&|&grep&mongo &drwxr-xr-x&2mongod&&&&&&&&&&&root&&&&&&&&&&4096&Mar&17&15:25mongo &root@namenode1:~#&ll&/mongo/ &total&4 &drwxr-xr-x&2&mongod&root&4096&Mar&17&15:27&data&
#将LC_ALL=&C&加入环境变量,以防启动出错
root@namenode1:~#&echo&&export&LC_ALL=&C&&&&/etc/profile&
#创建配置文件(将之前rpm包安装mongodb后的配置文件拷贝过来即可)
root@namenode1:~#&cat&/etc/mongod.conf &#&mongo.conf &&#where&to&log &logpath=/var/log/mongo/mongod.log &&logappend=true&&#&fork&and&run&in&background &fork&=&true&&#port&=&27017&&dbpath=/mongo/data &&#&location&of&pidfile &pidfilepath&=&/var/run/mongodb/mongod.pid &&#&Disables&write-ahead&journaling &#&nojournal&=&true&&#&Enables&periodic&logging&of&CPU&utilization&and&I/O&wait &#cpu&=&true&&#&Turn&on/off&security.&&Off&is&currently&the&default &#noauth&=&true&#auth&=&true&&#&Verbose&logging&output. &#verbose&=&true&&#&Inspect&all&client&data&for&validity&on&receipt&(useful&for &#&developing&drivers) &#objcheck&=&true&&#&Enable&db&quota&management &#quota&=&true&&#&Set&oplogging&level&where&n&is &#&&&0=off&(default) &#&&&1=W&#&&&2=R&#&&&3=both&#&&&7=W+some&reads &#diaglog&=&0&&#&Ignore&query&hints &#nohints&=&true&&#&Disable&the&HTTP&interface&(Defaults&to&localhost:27018). &#nohttpinterface&=&true&&#&Turns&off&server-side&scripting.&&This&will&result&in&greatly&limited &#&functionality &#noscripting&=&true&&#&Turns&off&table&scans.&&Any&query&that&would&do&a&table&scan&fails. &#notablescan&=&true&&#&Disable&data&file&preallocation. &#noprealloc&=&true&&#&Specify&.ns&file&size&for&new&databases. &#&nssize&=&&&#&Accout&token&for&Mongo&monitoring&server. &#mms-token&=&&&#&Server&name&for&Mongo&monitoring&server. &#mms-name&=&&&#&Ping&interval&for&Mongo&monitoring&server. &#mms-interval&=&&&#&Replication&Options &&#&in&replicated&mongo&databases,&specify&here&whether&this&is&a&slave&or&master &#slave&=&true&#source&=&master. &#&Slave&only:&specify&a&single&database&to&replicate &#only&=&master. &#&or &#master&=&true&#source&=&slave.&
启动mongodb
export&LC_ALL=&C&&root@namenode2:/usr/local/mongodb/bin#&mongod&-f&/etc/mongod.conf&&&
2.安装Rockmongo
RockMongo 是一个PHP5写的MongoDB管理工具。主要特征:使用宽松的New BSD License协议,速度快,安装简单,与mysql的phpmyadmin相似
root@namenode1:~#&apt-get&install&apache2&php5&php5-dev&php5-cli &root@namenode1:/etc/apache2#&cd&/var/www/ &root@namenode1:/var/www#&wgethttp://rock-/files/rockmongo-v1.0.11.zip &root@namenode1:/var/www#&unzip&rockmongo-v1.0.11.zip&
#二次编译php模块
root@namenode1:/var/www/mongo-php-driver-master#&phpize& &root@namenode1:/var/www/mongo-php-driver-master#&./configure&& &root@namenode1:/var/www/mongo-php-driver-master#&make&&&&makeinstall&
#找到php模块所在路径
root@namenode1:/var/www/mongo-php-driver-master#&&php&-i&|&grepextension_dir &extension_dir&=&/usr/lib/php5/&=&/usr/lib/php5/ &root@namenode1:/var/www/mongo-php-driver-master#&ll&/usr/lib/php5/ &total&2084 &-rwxr-xr-x&1&root&root&2016810&Mar&17&16:35&mongo.so &-rw-r--r--&1&root&root&&113072&Dec&12&16:53&pdo.so&
#php在debian系统所安装的路径在以下的位置,如果是其他系统需根据相对路径进行查找
root@namenode1:/var/www/mongo-php-driver-master#&ll/etc/php5/apache2/php.ini &-rw-r--r--&1&root&root&65755&Dec&12&16:53&/etc/php5/apache2/php.ini &root@namenode1:/var/www/mongo-php-driver-master#&vi/etc/php5/apache2/php.ini &
在733行加入内容,并保存退出&&
733&extension&=&mongo.so&&&
重启apache并查看url是否生效
root@namenode1:/etc/init.d/apache&restart&
访问以下地址
http://172.23.214.50/rockmongo/index.php?action=index.login&
可以看到如下图所示,已经可以正常显示mongodb的管理登陆界面,默认情况下用户名与密码默认都为admin
确认用户名和密码,登陆成功,如下所示
部署MongoDB主从复制:
1.规划如下:
服务器角色
172.23.214.47
172.23.214.50
2.配置主从
编辑Master配置文件:
root@namenode2:/var/log/mongo#&grep&-v&&#&&/etc/mongod.conf&|grep&-v&&^$& &&logpath=/var/log/mongo/mongod.log &&logappend=true&&fork&=&true&&port&=&27017&&dbpath=/mongo/data &&pidfilepath&=&/var/run/mongodb/mongod.pid &&rest&=&true&&maxConns=1024&&master=true&&&&&&&&&&&&&&&&&&&&&&&&&&&#将指定其为master &&oplogSize=2048&
编辑Slave配置文件
root@namenode1:/etc#&cat&mongod.conf.bak_slave&&|&grep&-v&&#&&|&grep&-v&^$& &&logpath=/var/log/mongo/mongod.log &&logappend=true&&fork&=&true&&port&=&27017&&dbpath=/mongo/data &&maxConns&=&1024&&slave&=&true&&&&&&&&&&&&&&&&&&&&&&&&&#指定其为slave &&source&=&172.23.214.47:27017&&&&&&&&&#指定master的主机地址及端口号 &&autoresync&=&true&&pidfilepath&=&/var/run/mongodb/mongod.pid &
编辑好配置文件,双方启动mongodb
root@namenode1:&mongod&--f&/etc/mongod.conf&
主库查看日志信息:
root@namenode2:/var/log/mongo#&cat&mongod.log &&Tue&Mar&18&13:24:32.115&[initandlisten]&connection&accepted&from172.23.214.50:5&connection&now&open) &
从库查看日志信息
root@namenode1:/var/log/mongo#&tail&mongod.log&&|&grep&47 &Tue&Mar&18&13:24:30.025&[initandlisten]&options:&{&autoresync:&true&,&config:&&/etc/mongod.conf&,&dbpath:&/mongo/data&,&fork:&&true&,&logappend:&&true&,logpath:&&/var/log/mongo/mongod.log&,&maxConns:&1024,&pidfilepath:&/var/run/mongodb/mongod.pid&,&port:&27017,&slave:&&true&,source:&&172.23.214.47:27017&&} &Tue&Mar&18&13:24:31.188&[replslave]&repl:&syncingfrom&host:172.23.214.47:27017&
验证:主库创建库,并在从库查看
&db.testcoll.find() &&show&collections &&db.testcoll.insert&(&{name:&tom&}) &&show&collections &system.indexes &testcoll &&db.testcoll.find() &{&&_id&&:&ObjectId(&5327dabc9dccab&),&name&&:&&tom&&}&
在从库上查看
show& &local&&&&&0.078125GB &testdb&&&&&0.203125GB &&use& &switched&to&db&testdb &&db.testcoll.find() &{&&_id&&:&ObjectId(&5327dabc9dccab&),&name&&:&&tom&&}&
查看从库日志
root@namenode1:/var/log/mongo#&tail&mongod.log &Tue&Mar&18&13:33:48.042&[replslave]&build&index&testdb.testcoll&{&_id:&1&} &Tue&Mar&18&13:33:48.042&[replslave]&&&&&&fastBuildIndexdupsToDrop:0 &Tue&Mar&18&13:33:48.043&[replslave]&build&index&done.&&scanned&1&totalrecords.&0&secs &Tue&Mar&18&13:33:48.062&[replslave]&resync:&done&with&initial&clone&for&db:testdb &Tue&Mar&18&13:34:55.757&[initandlisten]&connection&accepted&from127.0.0.1:3&connection&now&open) &Tue&Mar&18&13:35:53.979&[replslave]&repl:&&&checkpoint&applied&15operations &Tue&Mar&18&13:35:53.979&[replslave]&repl:&&&syncedTo:&Mar&18&13:35::1 &Tue&Mar&18&13:38:06.018&[conn1]&end&connection&127.0.0.1:32942&(0&connectionsnow&open) &Tue&Mar&18&13:38:23.981&[replslave]&repl:&&&checkpoint&applied&15operations &Tue&Mar&18&13:38:23.982&[replslave]&repl:&&&syncedTo:&Mar&18&13:38:145327dbc6:1&
登录主库管理页面,查看其状态信息(master:1)
2.mongodb副本集部署
服务器角色
172.23.214.47
172.23.214.50
172.23.215.61
首先屏蔽掉配置文件中的master/slave这等敏感信息,将配置文件还原为最初状态
最好配置hosts,如果不指hosts则写ip也可以
编辑配置文件:
3台主机配置文件都相同
root@namenode1:~#&grep&-v&&#&&/etc/mongod.conf&|&grep&-v&^$& &&logpath=/var/log/mongo/mongod.log &logappend=true&fork&=&true&port&=&27017&dbpath=/mongo/data &pidfilepath&=&/var/run/mongodb/mongod.pid &replSet&=&true&&&&&&&&&&&&&&#副本集的名字 &rest&=&true&maxConns=1024&oplogSize=2048&
先将master节点启动起来,登录想成为master的主机,启动mongod
root@&namenode2:~#&mongod&-f&/etc/mongod.conf&&
root@namenode2:/mongo/data#&mongo&
初始化副本集:
rs.initiate()&
{ &&&&&&_id&&:&&ture&,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#副本集的名字,要与配置文件对应 &&&&&&members&&:&[&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#指定副本集成员 &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0,&&&&&&&&&&&&&&&&&&&&&&&&&&#指定副本集成员的id号 &&&&&&&&&&&&&&&host&&:&172.23.214.47:27017&&&&&&&&#先将master添加进来而后再依次将其他成员添加进副本集 &&&&&&&&&&} &&&&&] &}&
等待大约30秒钟
&rs.initiate(&rsconf&) &{ &&&&&&info&&:&&Config&now&savedlocally.&&Should&come&online&in&about&a&minute.&,&&&&&&&#提示需要等待大约1分钟,如果及时查看副本集内容很可能报错 &&&&&&ok&&:&1&
查看副本集
&rs.conf()&&&
true:PRIMARY&rs.add(&172.23.214.47:27017&) &{&&ok&&:&1&} &&true:PRIMARY&rs.add(&172.23.215.61:27017&) &{&&ok&&:&1&}&
分别在slave上执行:
true:RECOVERING&rs.slaveOk()&
在master上创建库:
true:PRIMARY&use& &switched&to&db&testdb &&true:PRIMARY&for(i=1;i=100;i++)&db.testcoll.insert({Name:&User&+i,Age:i,Gender:&M&,preferbook:[&bluebook&,&yellow&book&]}) &
在slave节点上查看数据库,可以看到已经被通过到本地
true:RECOVERING&show& &local&&&&&2.GB &testdb&&&&0.203125GB &&rs.initiate()//先初始化,再通过rs.add等方法修改 &这里的config_object会记录在local.system.replset这个集合内,这个集合会自动的在副本集成员之间广播,而且我们不能直接修改他们,需要使用命令来改变它,例如(replSetInitiate&命令)。&
设定某节点的优先级
将一个普通数据节点修改为passive节点,也就是能同步数据、投票,但是不能成为primay
除了仲裁节点,其他每个节点都有个优先权,我们可以通过设置优先权来决定谁的成为primay的权重最大,MongoDB replica sets中通过设置priority的值来决定优先权的大小,这个值的范围是0--100,值越大,优先权越高。如果值是0,那么不能成为prima
如下所示:
(#这个环境是之前保留的镜像副本,以Host_Name进行添加的)
true:PRIMARY&rs.conf() &{ &&&&&&_id&&:&&true&, &&&&&&version&&:&3, &&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&host&&:&&namenode1:27017& &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&1, &&&&&&&&&&&&&&&host&&:&&namenode2:27017& &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&2, &&&&&&&&&&&&&&&host&&:&&datanode1:27017& &&&&&&&&&&} &&&&&] &}&
设置优先级别
#参考/Amaranthus/p/3616951.html
true:PRIMARY&cfg.members[0].priority=2& &&true:PRIMARY&rs.conf() &{ &&&&&&_id&&:&&true&, &&&&&&version&&:&3, &&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&host&&:&&namenode1:27017& &&&priority&:&2 &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&1, &&&&&&&&&&&&&&&host&&:&&namenode2:27017& &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&2, &&&&&&&&&&&&&&&host&&:&&datanode1:27017& &&&&&&&&&&} &&&&&] &}&
如果需要对副本集进行扩容,例如加入一台mongodb服务器进入副本集,需要先启动这个节点(最好是将数据事先拷贝一份启动,不然一个新的空的数据库进来同步可能会复制过多的数据而导致应用崩溃)
比如我们想将节点datanode1:27017 移除从而新加入节点test:27017
那么首先将集群中的datanode1:27017节点移除
true:PRIMARY&rs.status() &{ &&&&&&set&&:&&true&, &&&&&&date&&:&ISODate(&T04:38:52Z&), &&&&&&myState&&:&1, &&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&name&&:&&namenode1:27017&, &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&1, &&&&&&&&&&&&&&&stateStr&&:&&PRIMARY&, &&&&&&&&&&&&&&&uptime&&:&9510, &&&&&&&&&&&&&&&optime&&:&Timestamp(,&1), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T02:53:07Z&), &&&&&&&&&&&&&&&self&&:&true &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&1, &&&&&&&&&&&&&&&name&&:&&namenode2:27017&, &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&2, &&&&&&&&&&&&&&&stateStr&&:&&SECONDARY&, &&&&&&&&&&&&&&&uptime&&:&9183, &&&&&&&&&&&&&&&optime&&:&Timestamp(,&1), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T02:53:07Z&), &&&&&&&&&&&&&&&lastHeartbeat&&:&ISODate(&T04:38:51Z&), &&&&&&&&&&&&&&&lastHeartbeatRecv&&:&ISODate(&T04:38:51Z&), &&&&&&&&&&&&&&&pingMs&&:&0, &&&&&&&&&&&&&&&syncingTo&&:&&namenode1:27017& &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&2,&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&name&&:&&datanode1:27017&,&&&&&#将这个节点删除 &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&2, &&&&&&&&&&&&&&&stateStr&&:&&SECONDARY&, &&&&&&&&&&&&&&&uptime&&:&6345, &&&&&&&&&&&&&&&optime&&:&Timestamp(,&1), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T02:53:07Z&), &&&&&&&&&&&&&&&lastHeartbeat&&:&ISODate(&T04:38:50Z&), &&&&&&&&&&&&&&&lastHeartbeatRecv&&:&ISODate(&T04:38:51Z&), &&&&&&&&&&&&&&&pingMs&&:&0, &&&&&&&&&&&&&&&syncingTo&&:&&namenode1:27017& &&&&&&&&&&} &&&&&], &&&&&&ok&&:&1 &}&
true:PRIMARY&rs.remove(&datanode1:27017&) &Wed&Mar&19&12:40:44.497&DBClientCursor::init&call()&failed &Wed&Mar&19&12:40:44.498&JavaScript&execution&failed:&Error:&error&doing&query:failed&at&src/mongo/shell/query.js:L78 &Wed&Mar&19&12:40:44.498&trying&reconnect&to&127.0.0.1:27017 &Wed&Mar&19&12:40:44.498&reconnect&127.0.0.1:27017&ok&
再次查看副本集状态,发现datanode1已经没有了
true:PRIMARY&rs.status() &{ &&&&&&set&&:&&true&, &&&&&&date&&:&ISODate(&T04:41:03Z&), &&&&&&myState&&:&1, &&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&name&&:&&namenode1:27017&, &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&1, &&&&&&&&&&&&&&&stateStr&&:&&PRIMARY&, &&&&&&&&&&&&&&&uptime&&:&9641, &&&&&&&&&&&&&&&optime&&:&Timestamp(,&1), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T04:40:44Z&), &&&&&&&&&&&&&&&self&&:&true &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&1, &&&&&&&&&&&&&&&name&&:&&namenode2:27017&, &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&2, &&&&&&&&&&&&&&&stateStr&&:&&SECONDARY&, &&&&&&&&&&&&&&&uptime&&:&19, &&&&&&&&&&&&&&&optime&&:&Timestamp(,&1), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T04:40:44Z&), &&&&&&&&&&&&&&&lastHeartbeat&&:&ISODate(&T04:41:02Z&), &&&&&&&&&&&&&&&lastHeartbeatRecv&&:&ISODate(&T04:41:03Z&), &&&&&&&&&&&&&&&pingMs&&:&0, &&&&&&&&&&&&&&&lastHeartbeatMessage&&:&&syncing&to:&namenode1:27017&, &&&&&&&&&&&&&&&syncingTo&&:&&namenode1:27017& &&&&&&&&&&} &&&&&], &&&&&&ok&&:&1 &}&
接着配置启动test节点并启动,配置文件是相同的,启动之后它会自动复制数据。如果数据量过大,还是建议事先通过其它机制同步数据
在master加入新节点
true:PRIMARY&rs.add(&test:27017&) &{&&ok&&:&1&}&
true:PRIMARY&rs.status() &{ &&&&&&set&&:&&true&, &&&&&&date&&:&ISODate(&T04:43:08Z&), &&&&&&myState&&:&1, &&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&name&&:&&namenode1:27017&, &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&1, &&&&&&&&&&&&&&&stateStr&&:&&PRIMARY&, &&&&&&&&&&&&&&&uptime&&:&9766, &&&&&&&&&&&&&&&optime&&:&Timestamp(,&1), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T04:43:05Z&), &&&&&&&&&&&&&&&self&&:&true &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&1, &&&&&&&&&&&&&&&name&&:&&namenode2:27017&, &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&2, &&&&&&&&&&&&&&&stateStr&&:&&SECONDARY&, &&&&&&&&&&&&&&&uptime&&:&144, &&&&&&&&&&&&&&&optime&&:&Timestamp(,&1), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T04:43:05Z&), &&&&&&&&&&&&&&&lastHeartbeat&&:&ISODate(&T04:43:06Z&), &&&&&&&&&&&&&&&lastHeartbeatRecv&&:&ISODate(&T04:43:07Z&), &&&&&&&&&&&&&&&pingMs&&:&0, &&&&&&&&&&&&&&&syncingTo&&:&&namenode1:27017& &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&2, &&&&&&&&&&&&&&&name&&:&&test:27017&, &&&&&&&&&&&&&&&health&&:&1, &&&&&&&&&&&&&&&state&&:&6, &&&&&&&&&&&&&&&stateStr&&:&&UNKNOWN&, &&&&&&&&&&&&&&&uptime&&:&3, &&&&&&&&&&&&&&&optime&&:&Timestamp(0,&0), &&&&&&&&&&&&&&&optimeDate&&:&ISODate(&T00:00:00Z&), &&&&&&&&&&&&&&&lastHeartbeat&&:&ISODate(&T04:43:07Z&), &&&&&&&&&&&&&&&lastHeartbeatRecv&&:&ISODate(&T00:00:00Z&), &&&&&&&&&&&&&&&pingMs&&:&0, &&&&&&&&&&&&&&&lastHeartbeatMessage&&:&&still&initializing& &&&&&&&&&&} &&&&&], &&&&&&ok&&:&1 &}&
切换至test节点查看数据库
root@test:/var/log/mongo#&mongo &MongoDB&shell&version:&2.4.5 &connecting&to:&test &true:SECONDARY&show& &admin&&&&&(empty) &local&&&&&2.GB &testdb&&&&0.203125GB &true:SECONDARY&rs.slaveOk()&
部署Sharding集群
sharding通过将数据集分布于多个也称作分片(shard)的节点上来降低单节点的访问压力。每个分片都是一个独立的数据库,所有的分片组合起来构成一个逻辑上的完整意义的数据库。因此,分片机制降低了每个分片的数据操作量及需要存储的数据量
sharding的实现思路
选择一个合适索引而减少索引量,这种索引叫做重复索引
能够在索引中直接查找到所有要查询的索引,叫做覆盖索引,能够满足覆盖索引的条件并且排序次序又能够与索引的次序相同,这种次序是&3星&的
所以任何时候创建索引的目的一定要与搜索码完全匹配,至少保持一致
mongodb中可以使用db.mycoll.find().hint().explain()
来显示索引的查询过程mysql中可以使用 explain select XXX
副本集的集群在刚开始配置的时候有以下几个细节:
1、初始化:根据定义好的配置文件初始化,也可以让其系统本身进行简单初始化
2、简单初始化只是将同一个repiset节点的信息添加进来,但默认只初始化当前节点信息
如果想重新配置这个集群的话,可以实现将现有的配置信息读取出来而后在里面做设置之后并重新让后续的配置生效,而也可以在后续新增节点到集群中也可以将已经运行的节点从集群中移除出去,不管是新增和移除它们之间都会进行选举操作的
mongodb shard架构
1、config server : 元数据服务器,3台,1台为单点故障,而如果使用2台在选举时候,会无法得到分布式 &(zookeeper)在实验环境中有一个即可
2、mongos:路由,默认端口27017 ,启动的时候必须制定其config server为其指路
3、shard:能够存储分片的服务,可以是独立的服务器,也可以是replica set(副本集,生成环境建议使用此类型),因此生成环境中,一般都需要部署这样的集群
sharding集群
sharding目的:
&当单个节点所持有的数据太大,单个节点无法存储下的时候需要做shard
&如果某个单节点所持有的数据集太大,一个节点无法存储下的时候,则需要做shard
&如果某个单节点承载的读写并发请求过大时
&可预见的时间内,单个节点索引、经常被访问数据量,难在内存容纳下的时候,意味着可能用到swap,如果使用swap那么性能显著下降,对于此种情况需要用到shard
sharding主要做法无非将一个数据分割为多块,平局分布在各个节点,为了保证读写的性能,那么读的操作则不做离散,而写操作需要做离散操作
所以,mongodb主要是根据sharding key来决定分片切割的:
sharding key就是collection的索引,而collection的索引(sharding key)的选择至关重要。通常是第一个shard,也就是主shard
在shard上使用索引
使用顺序索引:
使用顺序插入时,写操作会集中在有限的shard上这样写操作很难均匀分布
使用离散索引:
会被分散到各节点中去,很难提高读性能
如何使用sharding key
假设我们数据库中有个表,表内数据分别为name,Age,Gender, 那么假设将一个collection 按照name切割,而name上创建的索引而是顺序索引,那就意味着是按范围进行切割的,那切割完成之后,那我们经常按照name查询,一般问题不大,查询的请求只交给config server即可,config server可以帮我们完成路由,而name则是charding key。
config server中保存的是每个shard和它所持有的数据的key的范围
如果是范围分区的话,那么我们想查询年龄在0-30岁的时候,则在哪个shard上则会保存在config server上?如果找不到响应的内容,那么则要对其进行全shard扫描
如果是离散的话,那么30在哪个服务器 40在哪里 。。等 config server全都会有记录
对应的key条目和它所对应的shard映射信息就是元数据,就在config server上
那如果我们对name来创建的,那么非常明显config server上所创建的就是某个名字和shard的映关系
所以如果按照age来进行查找的话,则没有办法去查找,那么这时则全shard扫描
如果大多数查询都是根据age来查询,而我们非选择sharding key为name 那么麻烦就大了
所以选择sharding key至关重要
真正选择shard的话 需要根据业务模型来选择的,一定要明白选择标准是什么。
sharding选择思路:
如果选择一个sharding key之后 有可能导致写不均匀,但做shard主要目的是离散写入均匀,所以我们在选择key的时候尽可能
1、尽可能范围选择shard
2、一旦落在某个shard以后仍然会变得过大,我们可以再进行将各chunk分布出去,则可以使用自合索引,比如:
将name和age同时当做sharding key 来使用
{name:1,age: 1} &#先根据name做分区,意味着作为name的范围匹配了之后落在同一个shard上会根据age再次分区,如果内容量过大的话,会再次分割开的而不会单独在这shard上操作
3、也可以使用三级索引
{name:1,age: 1,preferbooks} 有时我们存储了大量的数据进去,其会先对name进行分割发现落在某个shard的量过大,它会根据age再次分割,而后再次根据prefer books再次分割 这样可以使得写操作均匀分布,同样如果根据name范围查找的话,本来第一次分割是根据name分割的,很显然在一个范围内的用户通常会落在有限的shard上,所以读操作也做到了集中
在真正集群业务中并不是每个表都可以做shard的
比如有时候做shard可能带来很多问题
以博客为例:
我们以用户名做了shard 结果不同的用户可能被切割到不同shard中去,一个用户所发布的博文信息以及每个博文下的评论信息,每个用户发布的评论可能被存放在当前用户的shard上,当某个用户想查看自己博文下的所有评论信息的时候,那么评论的shard可能来自于多个用户,那么我对用户做了shard,也就意味着这些信息是根据用户所存储的 对应的用户所发布的评论也就有可能分布到多个shard上去 由此某个用户想查看自己博文下的所有评论,那么则会对其做全shard扫描,因此根据name来切割则是行不通的
以上的这种情况只能使用多个键
先根据文章和评论进行切割再根据用户名进行切割,意味着文章为标准,但同一个用户则放在有限的shard上去,这就是组合索引的好处
(尽可能保证前端的查询操作过于分散,这样就可以保证可以查询同一个或有限的shard)
如果文章与评论不是同一类的话:
那么既要考虑用户 又要考虑文章与评论 既然做分区了,如果用户本身信息量不是特别大的话,那么可以将一些有关联的表单独存放在一个库中
分片最主要的因素是选择sharding key
选择sharding key的标准:
1、应该在哪存数据
2、应该在哪得到希望的数据&
读数据尽可能来自同一个点,写数据尽可能分散处理
夸分片做查询,比单个分片查询性能要差 但是只要不是太多的分片(2-3个)那么让读只落在有限的分片
总结:sharing基本法则
1、sharing key 应该是主键
2、选择分sharding key的时候应该选择那些避免跨分片查询,但是又得保证写是均匀的
3、将有关联的表放置在独立库中
部署分片集群
服务器角色
172.23.215.61
config server、mongos、mongod
Debian GNU/Linux 7.2
172.23.214.50
config server、mongos、mongod
Debian GNU/Linux 7.2
172.23.214.47
mongos、mongod
Debian GNU/Linux 7.2
配置文件路径:
/mongo/etc/configsvr.conf &&/mongo/etc/mongod.conf &&/mongo/etc/mongos.conf&
日志路径:
config&server&&&&&&/var/log/mongo/mongod_config_server.log &&mongod&&&&&&&&&&&&&/var/log/mongo/mongod.log &&mongos&&&&&&&&&&&&&/var/log/mongo/mongos.log&
数据存放路径:
/mongo/data/configdb &&/mongo/data/configsvr &&/mongo/data/mongod&
1.建立副本集
修改各节点配置文件,如下所示:
root@datanode1:/mongo/etc#&cat&mongod.conf&&|&grep&-v&&#& &logpath=/var/log/mongo/mongod.log &logappend=true&fork&=&true&port&=&27017&dbpath=/mongo/data &pidfilepath&=&/var/run/mongodb/mongod.pid &replSet&=&rs0&rest&=&true&maxConns=1024&oplogSize=2048&
启动各个节点mongod
root@datanode1:/mongo/etc#&mongod&-f&mongod.conf&&
将master添加进副本集
root@datanode1:/mongo/etc#&mongo&rsconf&=&{&_id:&&rs0&,members:&[&{&_id:&0,&host:&&172.23.215.61:27017&&}&]&} &&{ &&&&&&_id&&:&&rs0&, &&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&host&&:&&172.23.215.61:27017& &&&&&&&&&&} &&&&&] &} &&
激活副本集
&rs.initiate(&rsconf&) &{ &&&&&&info&&:&&Config&now&savedlocally.&&Should&come&online&in&about&a&minute.&, &&&&&&ok&&:&1 &} &&rs.conf() &{ &&&&&&_id&&:&&rs0&, &&&&&&version&&:&1, &&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&host&&:&&172.23.215.61:27017& &&&&&&&&&&} &&&&&] &} &
陆续添加mongod节点
rs0:PRIMARY&rs.add(&172.23.214.50:27017&) &&rs0:PRIMARY&rs.add(&172.23.214.47:27017&)&
rs0:PRIMARY&rs.conf() &&{ &&&&&&&_id&&:&rs0&, &&&&&&&version&&:&3, &&&&&&&members&&:&[ &&&&&&&&&&{ &&&&&&&&&&&&&&&&_id&&:&0, &&&&&&&&&&&&&&&&host&&:&172.23.215.61:27017& &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&&_id&&:&1, &&&&&&&&&&&&&&&&host&&:&172.23.214.50:27017& &&&&&&&&&&}, &&&&&&&&&&{ &&&&&&&&&&&&&&&&_id&&:&2, &&&&&&&&&&&&&&&&host&&:&172.23.214.47:27017& &&&&&&&&&&} &&&&&&] &&}&
新建集合并插入数据,在从库查看是否同步
rs0:PRIMARY&use&test11; &switched&to&db&test11 &rs0:PRIMARY&for(i=1;i=100;i++)db.testcoll.insert({Name:&User&+i,Age:i,Gender:&M&,preferbook:[&bluebook&,&yellow&book&]})&
去从库查看
rs0:SECONDARY&show& &local&&&&&2.GB &test11&&&&&0.203125GB &testdb&&&&&0.203125GB&
2.配置config server
新建立配置文件,各节点内容相同
root@datanode1:/mongo/etc#&cat&configsvr.conf& &configsvr=true&dbpath=/mongo/data/configdb/ &port=27019&logpath=/var/log/mongo/mongod_config_server.log &logappend=true&fork=true&
启动config server
root@datanode1:/mongo/etc#&mongod&-f&configsvr.conf&
查看端口是否被监听
root@datanode1:/mongo/etc#&netstat&-lnt&|&grep&27 &&tcp&&&&&&&&0&&&&&&0&127.0.0.1:631&&&&&&&&&&&0.0.0.0:*&&&&&&&&&&&&&&&LISTEN&&&&& &&tcp&&&&&&&&0&&&&&&0&127.0.0.1:25&&&&&&&&&&&&0.0.0.0:*&&&&&&&&&&&&&&&LISTEN&&&&& &&tcp&&&&&&&&0&&&&&&0&0.0.0.0:27017&&&&&&&&&&&0.0.0.0:*&&&&&&&&&&&&&&&LISTEN&&&&& &&tcp&&&&&&&&0&&&&&&0&0.0.0.0:27019&&&&&&&&&&&0.0.0.0:*&&&&&&&&&&&&&&&LISTEN &
3.配置mongos
root@datanode1:/mongo/etc#&cat&mongos.conf& &&#&mongo.conf &&port=27020&&configdb=172.23.215.61:.214.47:.214.50:27019&&&&&&&#指定各config&server的ip地址或hostname,以及端口 &&fork&=&true&&logpath=/var/log/mongo/mongos.log &&chunkSize&=&100&&logappend&=&true&
启动路由(mongos)
root@datanode1:/mongo/etc#&mongos&-f&mongos.conf&
使用mongo命令连入mongos实例
root@datanode1:/mongo/etc#&&mongo&172.23.215.61:27020&
向分区集群中添加各shard服务器或副本集,如果添加的shard是副本集,则需要使用如下格式:
mongos&sh.addShard(&rs0/172.23.215.61:27017&) &&{&&shardAdded&&:&&rs0&,&&ok&&:&1&} &
mongos&&sh.status() &---&Sharding&Status&---& &&sharding&version:&{ &&&&&&_id&&:&1, &&&&&&version&&:&3, &&&&&&minCompatibleVersion&&:&3, &&&&&&currentVersion&&:&4, &&&&&&clusterId&&:ObjectId(&532fa30abfbf&) &} &&shards: &&&&&{&&&_id&&:&&rs0&,&&host&&:&rs0/172.23.214.47:.214.50:.215.61:27017&&} &&databases: &&&&&{&&&_id&&:&&admin&,&&partitioned&&:&false,&&&primary&&:&&config&} &&&&&{&&&_id&&:&&test11&,&&partitioned&&:&false,&&&primary&&:&&rs0&&} &&&&&{&&&_id&&:&&testdb&,&&partitioned&&:&false,&&&primary&&:&&rs0&&}&
4.启用sharding功能
mongodb的shard功能实现于collection级别,但若要在collection上启动shard,还需要事先其相关的数据库上启用之。在数据库上启用shard功能后,MongoDB会为其指定一个主shard。
激活数据库分片
switched&to&db&adminmongos &&mongos&db.runCommand(&{&enablesharding&:&&test11&&}&); &{&&ok&&:&1&} &mongos&db.runCommand(&{&enablesharding&:&&testdb&&}&); &{&&ok&&:&1&} &
激活collection分片
mongos&use&test11 &&mongos&show&collections &system.indexes &testcoll&&&&&&&&&&&#将此表进行激活 &
进入admin库,激活collection分片并配置shard key唯一
use&admin &&mongos&db.runCommand(&{&shardcollection&:&&test11.testcoll&,key&:&{_id&:&1&}&,&unique&:&true&&}&) &{&&collectionsharded&&:&&test11.testcoll&,&&ok&&:1&} &
查看分片状态信息
mongos&db.printShardingStatus(); &---&Sharding&Status&---& &&sharding&version:&{ &&&&&&_id&&:&1, &&&&&&version&&:&3, &&&&&&minCompatibleVersion&&:&3, &&&&&&currentVersion&&:&4, &&&&&&clusterId&&:ObjectId(&532fa30abfbf&) &} &&shards: &&&&&{&&&_id&&:&&rs0&,&&host&&:&rs0/172.23.214.47:.214.50:.215.61:27017&&} &&databases: &&&&&{&&&_id&&:&&admin&,&&partitioned&&:&false,&&&primary&&:&&config&} &&&&&{&&&_id&&:&&test11&,&&partitioned&&:&true,&&&primary&&:&&rs0&&} &&&&&&&&&&test11.testcoll &&&&&&&&&&&&&&shard&key:&{&&_id&&:&1&} &&&&&&&&&&&&&&chunks: &&&&&&&&&&&&&&&&&&&rs0&&&&&1 &&&&&&&&&&&&&&{&&_id&&:&{&&$minKey&&:&1&}&}&--&{&&_id&:&{&&$maxKey&&:&1&}&}&on&:&rs0&Timestamp(1,&0)& &&&&&{&&&_id&&:&&testdb&,&&partitioned&&:&true,&&&primary&&:&&rs0&&} &&&&&{&&&_id&&:&&test&,&&partitioned&&:&false,&&&primary&&:&&rs0&&}&
博文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&的更多文章
MongoDB的转变也正是10gen的转变,Dwight Merriman在一份声明中
网友评论TOP5
随着云计算、物联网、大数据、移动互联网的大发展,你应该知道这些。
讲师: 0人学习过讲师: 35人学习过讲师: 58人学习过
本周,搜狗浏览器被爆存在重大漏洞的消息被炒得沸沸扬
IE浏览器不支持很多CSS属性是出了名的,即便在支持的
又是一周匆匆而过。上周五、周六两天,2013年51CTO云
本书是关于EJB 3.0的专业技术教程,专注于EJB的概念、方法、开发过程的介绍。同时,本书还研究许多高端的EJB知识,使得开发者能
51CTO旗下网站}

我要回帖

更多关于 mongodb可以存储图片 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信