邢栋博客

邢栋博客,Action博客,记录工作和生活中的点点滴滴

mongodb复制集学习笔记
conf.conf 如下

bind_ip=192.168.1.100
 port = 28001

 logpath=/usr/local/mongodb/logs/28001
 logappend=true
 dbpath=/usr/local/mongodb/datas/28001
 replSet=imooc

 fork = true

查看当前复制集状态
rs.status()
或者
use admin;
db.adminCommand({replSetGetStatus:1})

查看当前复制集配置文件
rs.conf()

show log rs  #查看当前mongodb的日志

rs.stepDown(50) ## 把当前主节点50秒内降级为从节点

rs.isMaster()  # 查看节点信息

/usr/local/mongodb/bin/mongo 10.51.105.19:28001/admin
//建立配置
config={_id:"imooc",members:[{_id:0,host:"10.51.105.19:28001"}, {_id:1,host:"10.51.105.19:28002"},{_id:2,host:"10.51.105.19:28003"}]}
//配置仲裁节点
config.members[2]={"_id":2,"host":"10.51.105.19:28003","arbiterOnly":true}
//使配置文件生效,初始化
rs.initiate(config)  ### rs.reconfig(config) 重新加载配置文件

测试同步
主节点上
use study
imooc:PRIMARY> db.test.insert({"name":"xd"})
子节点上
imooc:SECONDARY> rs.slaveOk(1)
imooc:SECONDARY> use study
imooc:SECONDARY> db.test.find()

复制集配置文件参数

_id: 整数0
host:字符串 “127.0.0.1:27017“
arbiterOnly: 布尔值 true
priority:整数 0|1   该节点的优先级,如果设置为0,则永远不会升级为主节点
hidden:布尔值 true|false 或者 1|0 ,如果设置为false, 优先级 要设置为0,隐藏节点
votes:整数  0|1  具有投票
slaveDelay 整数 slaveDelay 3600  延迟节点 延迟多少秒进行复制
buildIndexes 布尔值  true|false 或者 1|0  主节点建立索引,子节点是否同步,如果设为false, 优先级 应设置为0

关于oplog
Oplog大小及意义
默认大小
     64位操作系统linux,windows为当前分区可用空间的5%,体积不会超过50G

imooc:PRIMARY> use local
imooc:PRIMARY> db.oplog.rs.status()
imooc:PRIMARY> db.oplog.rs.find().sort({$natural:-1}).limit(1).pretty()  //查看最近的一条数据,pretty()格式化输出

单节点启动复制后,如果要增加机器
rs.add({_id:1,host:" 10.51.105.19:28002"})

调整oplog大小
imooc:PRIMARY>rs.freeze(100)
imooc:PRIMARY>rs.stepDown(100)
然后退出kill掉这个进程,注释掉配置文件的  replSet=imooc,重新启动

>use local
>show table ## 可以看到    oplog.rs
> db.oplog.rs.find().sort({$natural:-1}).limit(1)
>db.temp.save( db.oplog.rs.find().sort({$natural:-1}).limit(1).next())
>db.oplog.rs.drop()
>db.createCollection("oplog.rs",{capped:true,size:1024 * 1024 * 1024 * 3})
>db.oplog.rs.save(db.temp.findOne())

步骤总结
1.将成员以单机模式启动
2.将oplog最新的一条记录保存到临时表中   db.temp.save( db.oplog.rs.find().sort({$natural:-1}).limit(1).next())

3.删除原来的oplog.rs集合
4.以创建封顶表的形式创建oplog.rs , db.createCollection("oplog.rs",{capped:true,size:1024 * 1024 * 1024 * 3})

5.将之前保存的原oplog中的最新操作插入到新的oplog.rs集合中   db.oplog.rs.save(db.temp.findOne())

6.将单节点模式的节点返回到复制集中

复制集状态查看
rs.status()  复制集状态查询
rs.printReplicationInfo() 查看oplog状态
rs.printSlaveReplicationInfo() 查看复制延迟
db.serverStatus() 查看状态详情

mongodb 监控工具
1.mongostat
     mongostat 常用选项
          --host      主机名,或者 主机名:端口

          --port     端口
         --username 用户(验证)
          --password 密码(验证)
          --authenticationDatabase 从哪个数据库进行验证
          --discover 发现集群其他节点
     重点关注字段
     getmore 大量的排序操作在进行
     faults 需要的数据不在内存中
     locked db 锁比例最高的库
     index miss 索引未命中
     qr|qw读写产生队列,供求失衡
2.mongotop 监控当前集合读写统计信息
           --host     主机名,或者 主机名:端口
          --port     端口
         --username 用户(验证)
          --password 密码(验证)
          --authenticationDatabase 从哪个数据库进行验证

安全篇
     开启认证
          auth 单点  auth=true
          keyfile  集群之前认证

    集群认证

          keyfile文件的生成(内容base64编码集[a-zA-Z+/],长度1000字节,权限chmod 600 keyFile)
          openssl rand -base64 102  > .keyFile
          调整权限
          chmod 600  .keyFile
          开启认证需要在配置文件中增加
          setParameter=enableLocalhostAuthBypass=1  ## 本地例外,mongo localhost:28001
           keyFile=/usr/local/mongodb/.keyFile


     创建用户(创建第一个用户role要为root,db为admin)
          db.createUser(
          {
               user:'action',#字符串
               pwd:'123',#字符串
               roles:[{role:'root',db:'admin'}] #数组+对象,
          })
          创建用户后,然后登录客户端
          use admin
          db.auth('admin','123')

      删除用户
          db.dropUser(<username>)  ###删除某个用户
          db.dropAllUsers() ###删除当前库的所有用户

     权限
          built-in roles
                 读写
                    read  readWrite
                  管理员
                    dbAdmin dbOwner userAdmin  clusterAdmin clusterManager clusterMonitor hostManager
                  备份
                    backup  restore
                   全局
                    readAnyDatabase readWriteAnyDatabase userAdminAnyDatabase dbAdminAnyDatabase
                    超级用户
                    root
             自定义角色
                   use admin
                    db.createRole(
                    {
                         role:<role_name>,
                         privileges:[
                             {resource:{db:<db_name>,collection:<coll_name>},actions:[<action_name>]}
                         ],
                         roles:[{role:<role_name>,db:<db_name>}]
                    })

                    db.runCommand({userInfo:'admin',showPrivileges:1})  ##查看权限详情


          修改用户名密码
          需要具备 changePassword changeOwnPassword
          db.changeUserPassword(<user_name>,<new_password>)
          db.updateUser(<user_name>,{update_object})

          权限伸缩
               如何增加权限
               db.grantRolesToUser(
                    <user_name>,
                    [{role:<role_name>,db:<db_name>}]
               )
               如何收缩权限
               db.revokeRolesFromUser(
                    <user_name>,
                    [{role:<role_name>,db:<db_name>}]
               )
mongodb添加用户报错TypeError:db.addUser is not a function

db.addUser('admin','admin123')

出现

2016-08-11T12:22:00.498+0800 E QUERY    [thread1] TypeError: db.addUser is not a function :

原因 新版的mongodb已经不支持addUser方法了。

db.createUser({user:'admin',pwd:'admin123',roles:['userAdminAnyDatabase']})

mongodb的备份和修复
mongodb的备份和修复
//备份
mongodump -d test -o backup  //把test数据库备份到backup文件夹下
//恢复
mongorestore -d foo --drop backup/test/  把备份的test数据库恢复到数据库foo中

//备份前加锁
use admin 
db.runCommand({"fsync":1,"lock":1})//返回{"info":"...","ok":1}
//解锁
db.$cmd.sys.unlock.findOne();//返回{"ok":1,"info":"unlock requested"}
db.cuurentOp();//为了确保已经解锁,返回{"inprog":[]}

//修复
未能正常停止MongoDb后应该修复数据库。要是未正常停止,下次启动服务器备份时MongoDb会提示
修复所有数据库最简单的方式就是 加上--repair;mongod --repair 来启动服务。
//修复数据库还能起到压缩数据的作用。闲置的空间在修复后被重新回收。
use test
db.repairDatabases()
通过驱动程序的话是:
{"repairDatabases":1}

MongoDB之MapReduce(转)
MongoDB MapReduce学习笔记
语法:
db.runCommand(
 { mapreduce : 字符串,集合名,
   map : 函数,见下文
   reduce : 函数,见下文
   [, output : 字符串,统计结果保存的集合。]
   [, query : 文档,会在发往map函数前,先用指定条件过滤文档]
   [, sort : 文档,会在发往map函数前,先给文档排序]
   [, limit : 整数,发往map函数的文档数量上限]
   [, keeptemp: 布尔值,链接关闭时临时结果集合是否保存]
   [, finalize : 函数,将reduce的结果送给这个函数,做最后的处理]
   [, scope : 文档,js代码中要用到的变量]
   [, jsMode : 布尔值,是否减少执行过程中BSON和JS的转换,默认true] //注:false时 BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可处理非常大的mapreduce,
   //true时BSON-->js-->map-->reduce-->BSON
   [, verbose : 布尔值,是否产生更加详细的服务器日志,默认true]
 }

);


测试数据:

2012020914555740.jpg


第一步是写映射(Map)函数,可以简单的理解成分组吧~
var m=function(){
    emit(this.age,this.name);
}

emit的第一个参数是key,就是分组的依据,这是自然是age了,后一个是value,可以是要统计的数据,下面会说明,value可以是JSON对象。
这样m就会把送过来的数据根据key分组了,可以想象成如下结构:

第一组
{key:0,values: ["name_6","name_12","name_18"]
第二组
{key:1,values: ["name_1","name_7","name_13","name_19"]
......
组中的key其实就是age的值了,values是个数组,数组内的成员都有相同的age!!。

第二步就是简化了,编写reduce函数
var r=function(key,values){
    var ret={age:key,names:values};
    return ret;
}
reduce函数会处理每一个分组,参数也正好是我们想像分组里的key和values。
这里reduce函数只是简单的把key和values包装了一下,因为不用怎么处理就是我们想要的结果了,然后返回一个对象。对象结构正好和我们想象的相符!:
{age:对应的age,names:[名字1,名字2..]}

最后,还可以编写finalize函数对reduce的返回值做最后处理:
var f=function(key,rval){
    if(key==0){
        rval.msg="a new life,baby!";
    }
    return rval
}

这里的key还是上面的key,也就是还是age,rval是reduce的返回值,所以rval的一个实例如:{age:0,names:["name_6","name_12","name_18"]},
这里判断 key 是不是 0 ,如果是而在 rval 对象上加 msg 属性,显然也可以判断 rval.age==0,因为 key 和 rval.age 是相等的嘛!!
这里其他的选项就不说了,一看就知道。

执行:
db.runCommand({
    mapreduce:"t",//集合名字
    map:m,
    reduce:r,
    finalize:f,
    out:"t_age_names"
    }
)

2012020915382353.jpg


MongoDB安全认证基础

开启安全检查之前,一定要至少有个管理员帐号
use admin
db.addUser("root","abcd");

use test
db.addUser("test_user","efgh");
db.addUser("read_only","ijkl",true);//加入 true 只读权限

重启服务,加入--atuh命令行选项,开启安全检查
use test
db.test.find(); //提示error:

db.auth("read_only","ijkl"); //返回1
db.test.find();  //返回数据
db.test.insert({"x":2}); // unauthhorized 

db.auth("test_user","efgh");//返回1
db.test.insert({"x":2}); //正常
db.test.find(); //正常,返回数据

show dbs;  //返回 assert:assert failed...
use admin
db.auth("root","abcd")//返回1
show dbs  //返回数据库列表

数据库的用户帐号是以文档的形式存储在system.users 集合里面。
文档的结构是 {"user":username,"read_only":true,"pwd": password hash}
可以删除
db.auth("test_user","efgh");//返回1
db.system.users.remove({"user":"test_user"})
db.auth("test_user","efgh"); //返回0

mongodb的分页
第一种
var page1 = db.my_collection.find().limit(10)  
var latest=null;while(p1.hasNext()){latest=p1.next()}
db.my_collection.find({"num":{"$gt":latest.num}}).limit(10)

第二种
db.my_collection.limit(10)//第一页
db.my_collection.skip(10).limit(10)//第二页
db.my_collection.skip(20).limit(10)//第三页


thinkphp3.2同时支持mysql和mongodb

1.如果只是支持mysql,就不用说了,先说说只支持mongodb吧

在config.php中

<?php
return array(
//'配置项'=>'配置值'
'DB_TYPE'=>'mongo',
'DB_HOST'=> '127.0.0.1', 
'DB_USER'=>'',      
'DB_PWD'=>'',        
'DB_PORT'=>'27017',
'DB_NAME'=> 'test',     
 'DB_PREFIX'=> '',

);

新建一个TestModel.class.php文件

<?php
namespace Home\Model;
use Think\Model\MongoModel;
Class TestModel extends MongoModel{

}
?>

然后在控制器中 

$user =  D("users")->select();

var_dump($user);

就可以了。


2.同时支持mysql和mongodb

测试后发现只能以mogodb为主是可以使用的。

在config.php配置文件中

<?php
return array(
//'配置项'=>'配置值'
'DB_TYPE'=>'mongo',
'DB_HOST'=> '127.0.0.1', 
'DB_USER'=>'',      
'DB_PWD'=>'',        
'DB_PORT'=>'27017',
'DB_NAME'=> 'test',     
 'DB_PREFIX'=> '',

'DB_MYSQL' => array(
'DB_TYPE' => 'mysql', // 数据库类型
'DB_HOST' => 'localhost', // 服务器地址
'DB_NAME' => 'test, // 数据库名
'DB_USER' => 'root', // 用户名
'DB_PWD' => '1314', // 密码
'DB_PORT' => 3306, // 端口
'DB_PREFIX' => 'action_' // 数据库表前缀
),

);


然后mongodb的调用方法不变,mysql调用方法

mysql的可以这样:
$user = M('user','action_','DB_MYSQL')->select();
var_dump($user):


手册介绍地址:http://document.thinkphp.cn/manual_3_2.html#connect_db

windows下装php的mongodb扩展

windows下装php的mongodb扩展,遇到一个问题 ,折腾了半天

问题:phpinfo中看不到mongo的信息,扩展都已经配置进去,apache重启也没有报错

我的电脑环境是装的wampserver,php版本是5.5.12,X64,我先下载mongodb的安装包mongodb-win32-x86_64-2008plus-ssl-3.0.3-signed.msi(官网可下载到),如日志http://xingdong365.com/network/32.html 已经正常了。

下面需要装扩展文件,找的是对应的版本 php_mongo-1.6.8-5.5-vc11-x86_64.dll (地址:http://windows.php.net/downloads/pecl/releases/mongo/1.6.8/)。复制到php的ext目录下,又更改php.ini,wampserver环境也已经在扩展php_mongo 打上了对钩。感觉没啥问题。可就是在访问phpinfo.php的时候没有mongo的信息。

折腾的半天,最后找了一个php_mongo-1.4.5-5.5-vc11-x86_64.dll(地址:http://download.csdn.net/download/dupingjin/7577217),终于解决了。看来还是版本问题。



优惠券
广告位-淘宝
最新微语