MongoDB基于Linux操作
mongodb简介
MongoDB 是由C++语言编写的开源数据库系统,提供高性能,高可用性和自动扩展。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 将数据存储为一个文档。MongoDB是一个基于分布式文件存储的数据库。
MongoDB的中的一条记录就是一个文档,是一个数据结构,由字段和值对组成.MongoDB文档与JSON对象类似。字段的值有可能包括其它文档,数组以及文档数组。
使用文档的优势在于:
- 文档(即对象)对应于许多编程语言中的本机数据类型。
-
嵌入文档及数组减少了昂贵的加入操作的需求。
-
动态的设计模式支持流畅的多态。
部署
接下来对MongoDB的部署都是基于Linux系统完成的
官网下载:https://www.mongodb.com/download
文档地址:
安装
安装准备: 准备Redhat或Centos6.2以上系统 关闭iptables&Senlinux 配置IP地址和hosts解析 关闭hugepage大页内存
1、上传文件
mkdir /data 创建data目录 cd /data 使用xshell上传软件
2、解压软件
tar xf mongodb-linux-x86_64-rhel62-3.2.10.tgz mv mongodb-linux-x86_64-rhel62-3.2.10 mongodb
3、创建mongodb管理用户
useradd mongod 创建用户
passwd mongod 设置密码
4、修改目录授权
chown -R mongod.mongod /data/mongodb
5、切换或登录mongod用户
su - mongod
6、创建mongod的关键目录
mkdir -p /data/data/mongodb/data /data/data/mongodb/log /data/data/mongodb/conf
cd /data/mongodb
7、修改环境变量
vim ~/.bash_profile 添加一行: export PATH=/data/data/mongodb/bin:$PATH 配置生效一下: source ~/.bash_profile
8、启动mongodb
mongod --logpath=/data/data/mongodb/log/mongodb.log --dbpath=/data/data/mongodb/data/ --fork
9、登录mongodb测试
mongo
执行完上述流程登录时会有警告,不会影响正常的操作,但是可以通过修改配置来解决这个警告
root用户下
第一步:
vim /etc/rc.local
然后添加以下代码
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then echo never > /sys/kernel/mm/transparent_hugepage/enabled fi if test -f /sys/kernel/mm/transparent_hugepage/defrag; then echo never > /sys/kernel/mm/transparent_hugepage/defrag fi
第二步:
vim /etc/security/limits.conf
删掉以下内容(最后两行)
* - nofile 65535
修改完成后,重启虚拟机后,启动mongodb
reboot -------------------------------------------------------------------------------------------- su - mongod mongod --logpath=/data/data/mongodb/log/mongodb.log --dbpath=/data/data/mongodb/data/ --fork
再次登录就不会报warning了
补充:
注: $ mongod --help --dbpath:数据存放路径 --logpath:日志文件路径 --logappend:日志输出方式 --port:启用端口号 --fork:在后台运行 --auth:是否需要验证权限登录(用户名和密码) --bind_ip:限制访问的ip
Kill模式 kill -2 PID kill -4 PID 内置模式 admin> db.shutdownServer() 或 admin> db.adminCommand({shutdown:1}) 或 $ mongod -f mongodb.conf --shutdown
Mongodb可以通过命令行方式和配置文件的方式来启动,配置文件: $ su - mongod -------------------- $ vim mongodb.conf -------------------- port=27017 dbpath=/db/data/ logpath=/db/log/mongodb.log logappend=true fork=true -------------------- $ mongod -f mongodb.conf 启动 $ mongod –f mongodb.conf –shutdown 关闭 连接测试 $ mongo -------------------- MongoDB shell version: 3.2.6 connecting to: test
帮助 help KEYWORDS.help KEYWORDS.[TAB] 常用操作 查看当前db版本 test> db.version() 3.2.6 显示当前数据库 test> db test 或 > db.getName() test 查询所有数据库 test> show dbs local 0.000GB 切换数据库 > use local switched to db local 显示当前数据库状态 test> use local switched to db local local> db.stats() 查看当前数据库的连接机器地址 > db.getMongo() connection to 127.0.0.1 指定数据库进行连接 默认连接本机test数据库 $mongo 192.168.1.24/admin 创建数据库: 当use的时候,系统就会自动创建一个数据库。 如果use之后没有创建任何集合。 系统就会删除这个数据库。 删除数据库 如果没有选择任何数据库,会删除默认的test数据库 //删除test数据库 test> show dbs local 0.000GB test 0.000GB test> use test switched to db test test> db.dropDatabase() { "dropped" : "test", "ok" : 1 } 创建集合 方法1 admin> use app switched to db app app> db.createCollection('a') { "ok" : 1 } app> db.createCollection('b') { "ok" : 1 } > show collections //查看当前数据下的所有集合 a b 或 > db.getCollectionNames() [ "a", "b" ] d9f7b524713d"), "username" : "mongodb" } 方法2:当插入一个文档的时候,一个集合就会自动创建。 admin> use app switched to db app app> db.c.insert({username:"mongodb"}) WriteResult({ "nInserted" : 1 }) app> show collections a b c app> db.c.find() { "_id" : ObjectId("5743c9a9bf72d9f7b524713d"), "username":"mongodb" } 删除集合 app> use app switched to db app app> db.log.drop() //删除集合 重命名集合 //把log改名为log1 app> db.log.renameCollection("log1") { "ok" : 1 } app> show collections a b c log1 app> 插入数据 app> for(i=0;i<10000;i++){ db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()}); } 查询集合中的记录数 app> db.log.find() //查询所有记录 注:默认每页显示20条记录,当显示不下的的情况下,可以用it迭代命令查询下一页数据。 设置每页显示数据的大小: > DBQuery.shellBatchSize=50; //每页显示50条记录 50 app> db.log.findOne() //查看第1条记录 app> db.log.count() //查询总的记录数 删除集合中的记录数 app> db.log.remove({}) //删除集合中所有记录 > db.log.distinct("name") //查询去掉当前集合中某列的重复数据 查看集合存储信息 app> db.log.stats() app> db.log.dataSize() //集合中数据的原始大小 app> db.log.totalIndexSize() //集合中索引数据的原始大小 app> db.log.totalSize() //集合中索引+数据压缩存储之后的大小 app> db.log.storageSize() //集合中数据压缩存储的大小 app> db.log.totalSize function () { var total = this.storageSize(); var totalIndexSize = this.totalIndexSize(); if (totalIndexSize) { total += totalIndexSize; } return total; } app> db.log.storageSize function () { return this.stats().storageSize; }
用户管理
MongoDB数据库默认是没有用户名及密码的,即无权限访问限制。为了方便数据库的管理和安全,需创建数据库用户。
用户创建语法:
{ user: "<name>", pwd: "<cleartext password>", customData: { <any information> }, roles: [ { role: "<role>", db: "<database>" } | "<role>", ... ] }
-------------------------------------
user字段:用户的名字;
pwd字段:用户的密码;
cusomData字段:为任意内容,例如可以为用户全名介绍;
roles字段:指定用户的角色,可以用一个空数组给新用户设定空角色;
role字段,可以指定内置角色和用户定义的角色。
官方文档解释:https://docs.mongodb.com/manual/reference/built-in-roles/
验证数据库:
创建用户时你use到的库,在将来登录时候,使用以下方式登录,否则是登录不了的
开发用户:
use test db.createUser( { user: "test", pwd: "123", roles: [ { role: "readWrite", db: "mongo1" } ] } )
----------------------------
登录验证:
mongo -utest -p123 10.0.0.200
创建超级管理员:管理所有数据库
$ mongo use admin db.createUser( { user: "root", pwd: "root123", roles: [ { role: "root", db: "admin" } ] } )
-----------------------
登录验证:
1、mongo -uroot -proot123 10.0.0.200/admin
-----------------------
2、
mongo
use admin
db.auth('root','root123')
查询mongodb中的用户信息
mongo -uroot -proot123 10.0.0.200/admin
db.system.users.find().pretty()
定义指定数据库权限验证
自定义数据库 创建app数据库的管理员:先登录到admin数据库 use app db.createUser( { user: "admin", pwd: "admin", roles: [ { role: "dbAdmin", db: "app" } ] } ) db.auth('admin','admin') 创建app数据库读、写权限的用户: use app db.createUser( { user: "app01", pwd: "app01", roles: [ "readWrite" ] } ) 创建app数据库读写权限的用户并具有clusterAdmin权限: use app db.createUser( { user: "app04", pwd: "app04", roles: [ { role: "readWrite", db: "app" }, { role: "clusterAdmin", db: "admin" } ] } ) db.createUser( { user: "app02", pwd: "app02", roles: [ "read" ] } ) 创建app数据库读写权限的用户并对test数据库具有读权限: use app db.createUser( { user: "app03", pwd: "app03", roles: [ { role: "readWrite", db: "app" }, { role: "read", db: "test" } ] } )
删除用户
# mongo -uroot –proot 192.168.1.24/admin use app db.dropUser("app01")
mongodb复制集简介
一组Mongodb复制集,就是一组mongod进程,这些进程维护同一个数据集合。复制集提供了数据冗余和高等级的可靠性,这是生产部署的基础。 保证数据在生产部署时的冗余和可靠性,通过在不同的机器上保存副本来保证数据的不会因为单点损坏而丢失。能够随时应对数据丢失、机器损坏带来的风险,牛逼到不行。 换一句话来说,还能提高读取能力,用户的读取服务器和写入服务器在不同的地方,而且,由不同的服务器为不同的用户提供服务,提高整个系统的负载,简直就是云存储的翻版... 一组复制集就是一组mongod实例掌管同一个数据集,实例可以在不同的机器上面。实例中包含一个主导,接受客户端所有的写入操作,其他都是副本实例,从主服务器上获得数据并保持同步。 主服务器很重要,包含了所有的改变操作(写)的日志。但是副本服务器集群包含有所有的主服务器数据,因此当主服务器挂掉了,就会在副本服务器上重新选取一个成为主服务器。 每个复制集还有一个仲裁者,仲裁者不存储数据,只是负责通过心跳包来确认集群中集合的数量,并在主服务器选举的时候作为仲裁决定结果。
一个包含3个mongod的复制集架构如下所示:
如果主服务器失效,会变成:
如果加上可选的仲裁者:
如果主服务器失效:
Replcation Set配置过程详解
1、规划
三个以上的mongodb节点(或多实例)
多实例:
(1)多个端口:28017、28018、28019、28020
(2)多套目录:
mkdir -p /data/mongodb/28017/conf /data/mongodb/28017/data /data/mongodb/28017/log mkdir -p /data/mongodb/28018/conf /data/mongodb/28018/data /data/mongodb/28018/log mkdir -p /data/mongodb/28019/conf /data/mongodb/28019/data /data/mongodb/28019/log mkdir -p /data/mongodb/28020/conf /data/mongodb/28020/data /data/mongodb/28020/log
(3) 多套配置文件
/data/mongodb/28017/conf/mongod.conf /data/mongodb/28018/conf/mongod.conf /data/mongodb/28019/conf/mongod.conf /data/mongodb/28020/conf/mongod.conf
(4)配置文件内容
vim /data/mongodb/28017/conf/mongod.conf ------------------------------------------------------- systemLog: destination: file path: /data/mongodb/28017/log/mongodb.log logAppend: true storage: journal: enabled: true dbPath: /data/mongodb/28017/data directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: true processManagement: fork: true net: port: 28017 replication: oplogSizeMB: 2048 replSetName: my_repl ----------------------------------------------------- cp /data/mongodb/28017/conf/mongod.conf /data/mongodb/28018/conf/ cp /data/mongodb/28017/conf/mongod.conf /data/mongodb/28019/conf/ cp /data/mongodb/28017/conf/mongod.conf /data/mongodb/28020/conf/ ------------------------------------------------------- sed 's#28017#28018#g' /data/mongodb/28018/conf/mongod.conf -i sed 's#28017#28019#g' /data/mongodb/28019/conf/mongod.conf -i sed 's#28017#28020#g' /data/mongodb/28020/conf/mongod.conf -i
(5)启动多个实例备用
mongod -f /data/mongodb/28017/conf/mongod.conf mongod -f /data/mongodb/28018/conf/mongod.conf mongod -f /data/mongodb/28019/conf/mongod.conf mongod -f /data/mongodb/28020/conf/mongod.conf
查看所有280端口的实例
netstat -lnp|grep 280
2、配置复制集:
(1)1主2从,从库普通从库
mongo --port 28017 admin config = {_id: 'my_repl', members: [ {_id: 0, host: '10.0.0.200:28017'}, {_id: 1, host: '10.0.0.200:28018'}, {_id: 2, host: '10.0.0.200:28019'}] } rs.initiate(config)
3、复制集管理操作:
(1)查看复制集状态:
rs.status(); //查看整体复制集状态
rs.isMaster(); // 查看当前是否是主节点
(2)添加删除节点
rs.add("ip:port"); // 新增从节点 rs.remove("ip:port"); // 删除一个节点 rs.addArb("ip:port"); // 新增仲裁节点
添加arbiter节点
1、连接到主节点 [[email protected] ~]$ mongo --port 28017 admin 2、添加仲裁节点 my_repl:PRIMARY> rs.addArb("10.0.0.200:28020") 3、查看节点状态 my_repl:PRIMARY> rs.isMaster() { "hosts" : [ "10.0.0.200:28017", "10.0.0.200:28018", "10.0.0.200:28019" ], "arbiters" : [ "10.0.0.200:28020" ], }
删除一个节点
rs.remove("ip:port");
特殊节点
arbiter节点:主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务
hidden节点:隐藏节点,不参与选主,也不对外提供服务。
delay节点:延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,
所以通常会配合hidden(隐藏)
一般情况下会将delay+hidden一起配置使用
延时节点
延时节点的数据集是延时的,因此它可以帮助我们在人为误操作或是其他意外情况下恢复数据。举个例子,当应用升级失败,或是误操作删除了表和数据库时,我们可以通过延时节点进行数据恢复。
配置延时节点(一般延时节点也配置成hidden)
cfg=rs.conf() cfg.members[1].priority=0 cfg.members[1].hidden=true cfg.members[1].slaveDelay=120 rs.reconfig(cfg)
需求:把28019设置为hidden和delay
my_repl:PRIMARY> rs.status() { "members" : [ { "_id" : 0, "name" : "10.0.0.200:28017", }, { "_id" : 1, "name" : "10.0.0.200:28018", }, { "_id" : 3, "name" : "10.0.0.200:28020", }, { "_id" : 4, "name" : "10.0.0.200:28019", } cfg=rs.conf() cfg.members[3].priority=0 cfg.members[3].hidden=true cfg.members[3].slaveDelay=120 rs.reconfig(cfg) --------------------------- 取消以上配置 cfg=rs.conf() cfg.members[3].priority=1 cfg.members[3].hidden=false cfg.members[3].slaveDelay=0 rs.reconfig(cfg) -------------------------------- 配置成功后,通过以下命令查询配置后的属性 rs.conf();
MongoDB分片(Sharding)技术简介
1、分片的目的
高数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大的查询量会将单机的CPU耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存而将压力转移到磁盘IO上。 为了解决这些问题,有两个基本的方法: 垂直扩展和水平扩展。
垂直扩展:增加更多的CPU和存储资源来扩展容量。
水平扩展:将数据集分布在多个服务器上。水平扩展即分片。
2、分片集群架构
Config Server
存储集群所有节点、分片数据路由信息。默认需要配置3个Config Server节点。
Mongos
提供对外应用访问,所有操作均通过mongos执行。一般有多个mongos节点。数据迁移和数据自动平衡。
Mongod
存储应用数据记录。一般有多个Mongod节点,达到数据分片目的。
Mongos的路由功能
当数据写入时,MongoDB Cluster根据分片键设计写入数据。
当外部语句发起数据查询时,MongoDB根据数据分布自动路由至指定节点返回数据。
分片建shard key
必须为分片collection 定义分片键。
基于一个或多个列(类似一个索引)。
分片键定义数据空间。
想象key space 类似一条线上一个点数据。
一个key range 是一条线上一段数据。
我们可以按照分片键进行Range和Hash分片
分片键选择建议:
递增的sharding key
数据文件挪动小。(优势)
因为数据文件递增,所以会把insert的写IO永久放在最后一片上,造成最后一片的写 热点。
同时,随着最后一片的数据量增大,将不断的发生迁移至之前的片上。
随机的sharding key
数据分布均匀,insert的写IO均匀分布在多个片上。(优势)
大量的随机IO,磁盘不堪重荷。
混合型key
大方向随机递增。
小范围随机分布。
范围(RANGE)分片:
Sharded Cluster支持将单个集合的数据分散存储在多shard上,用户可以指定根据集合内文档的某个字段即shard key来进行范围分片(range sharding)。
Hash分片
Hash分片与范围分片互补,能将文档随机的分散到各个chunk,充分的扩展写能力,弥补了范围分片的不足,但不能高效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满足条件的文档。
注意事项:
分片键是不可变。
分片键必须有索引。
分片键大小限制512bytes。
分片键用于路由查询。
MongoDB不接受已进行collection级分片的collection上插入无分片键的文档(也不支持空值插入)