NOSQL数据库与关系数据库对比
# NOSQL数据库的分类 # 与Mysql的概念对比常用命令
-
常用操作
db.help(); //Help查看命令提示 db.yourColl.help(); //Help查看命令提示 db.youColl.find().help(); //Help查看命令提示 use yourDB; //切换/创建数据库 show dbs; //查询所有数据库 db.dropDatabase(); //删除当前使用数据库 db.stats(); //显示当前db状态
-
Collection聚集集合操作
// 固定集合指的是事先创建而且大小固定的集合,如果空间不足,最早的文档就会被删除 db.createCollection(“collName”, {size: 20, capped: 5, max: 100}); //创建一个聚集集合(table) db.getCollection("account”); //得到指定名称的聚集集合(table)
-
用户相关操作
db.addUser("userName", "pwd123", true); //添加用户、设置密码、是否只读 db.auth("userName", "123123”); //数据库认证、安全模式 show users; //显示当前所有用户 db.removeUser("userName”); //删除用户
-
聚集集合查询
db.userInfo.find(); //查询所有记录 db.userInfo.distinct("name”); //会过滤掉name中的相同数据,相当于:select distict name from userInfo; db.userInfo.find({"age": 22}); //相当于:select * from userInfo where age = 22; db.userInfo.find({age: {$gt: 22}}); //查询age > 22的记录 db.userInfo.find({age: {$gte: 23, $lte: 26}}); //查询age >= 23 并且 age <= 26 db.userInfo.find({name: /mongo/}); //查询name中包含 mongo的数据 db.userInfo.find().sort({age: 1}); //按照年龄升序 db.userInfo.find().sort({age: -1}); //按照年龄降序 db.userInfo.find({name: 'zhangsan', age: 22}); //查询name = zhangsan, age = 22的数据 db.userInfo.find().limit(5); //查询前5条数据 db.userInfo.find({$or: [{age: 22}, {age: 25}]}); //or与 查询 db.userInfo.findOne(); //查询第一条数据 db.userInfo.find().limit(1); //查询第一条数据
-
索引(mongodb会将全部索引读入内存中)
db.userInfo.ensureIndex({name: 1}); //创建索引 db.userInfo.getIndexes(); //查询当前聚集集合所有索引 db.users.dropIndex("name_1”); //删除指定索引
MongoDB数据类型
安全和认证
(1) 每个MongoDB实例中的数据库都可以有许多用户。如果开启了安全性检查,则只有数据库认证用户才能执行读或者写操作。
(2) 在认证的上下文中,MongoDB会将普通的数据作为admin数据库处理。admin数据库中的用户被视为超级用户(即管理员)。
3)在认证之后,管理员可以读写所有数据库,执行特定的管理命令,如listDatabases和shutdown。
(4)在开启安全检查之前,一定要至少有一个管理员账号。
安装MongoDB
(1) 在D 盘创建一个目录,D:\MongoDB\Server\4.0\data
(2) 启动数据库
mongod.exe -dbpath="D:\MongoDB\Server\4.0\data”
./mongod --fork --dbpath=/opt/mongodb/data //后台启动
./mongod -f mongodb.cfg //配置文件启动
(3) 基本配置/opt/mongodb/mongodb.cfg
dbpath=/opt/mongodb/data //数据存放目录
logpath=/opt/mongodb/logs/mongodb.log //日志存放路径
logappend=true //以追加的方式记录日志
fork=true //以后台方式运行进程
bind_ip=47.107.182.164 //mongodb 所绑定的ip 地址
port=27017 //mongodb 进程所使用的端口号,默认为27017
(4) 建立完数据库之后,会在我们的MongoDB\data 文件夹下,生成一些文件夹和文件。
在journal 文件夹中会存储相应的数据文件,也就是说被二进制码转换过的json 形式来存储所有的数据模型。
MongoDB 的应用场景
-
适合的场景
(1) 网站实时数据:mongoDB非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
(2) 数据缓存:由于性能很高,MongoDB 也适合作为信息基础设施的缓存层。在系统重启之后,由MongoDB搭建的持久化缓存层可以避免下层的数据源过载。
(3) 大尺寸、低价值数据存储:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
(4) 高伸缩性场景:MongoDB 非常适合由数十或数百台服务器组成的数据库。MongoDB 的路线图中已经包含对MapReduce 引擎的内置支持。
(5) 对象或JSON 数据存储:MongoDB 的BSON 数据格式非常适合文档化格式的存储及查询。
(6)可以用来做文件服务器(图片、pdf等) -
不适合的场景
(1) 高度事务性系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
(2) 传统的商业智能应用:针对特定问题的BI 数据库会产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
(3) 需要复杂SQL 查询的问题。
MongoDB复(副)本集与分片原理
概念解析
(1) 复(副)本集: 每个复(副)本集中存储的数据是相同的,相当于主备方式的数据冗余,目的是为了容灾。
(2) 分片: 是为了数据的拓展,按照片键进行结点划分,数据根据片键存储到对应的服务器上。
(3) 片键(shard key): 设置分片时,需要从集合里面选一个键,用该键的值作为数据拆分的依据。
集群部署方案中有三类角色
(1) 实际数据存储结点
(2) 配置文件存储结点
(3) 路由接入节点(在分片的情况下起到负载均衡的作用)
混合部署方式
-
部署关系
(1) 连接的客户端直接与路由结点相连
(2) 从配置结点上查询数据,根据查询结果到实际的存储结点上查询和存储数据
(MongoDB的部署方案有单机部署、复本集(主备)部署、分片部署、复本集与分片混合部署。)
-
混合部署方式下向MongoDB写数据的流程
-
混合部署方式下读MongoDB里的数据流程
-
副本集的写
对于复本集,又有主和从两种角色,写数据和读数据也是不同,写数据的过程是只写到主结点中,由主结点以异步的方式同步到从结点中
-
副本集的读
而读数据则只要从任一结点中读取,具体到哪个结点读取是可以指定的
-
分片原理
-
存储节点
(1) 对于MongoDB的分片,假设我们以某一索引键(ID)为片键,ID的区间[0,50],划分成5个chunk,分别存储到3个片服务器中。
(2) 假如数据量很大,需要增加片服务器时可以只要移动chunk来均分数据即可。
-
配置结点
存储配置文件的服务器其实存储的是片键与chunk以及chunk与server的映射关系,用上面的数据表示的配置结点存储的数据模型如图:
-
MongoDB的实战部署
MongoDB 高可用方案-主从搭建(Master-Slaver)
-
简介
(1) 这个是最简答的集群搭建,不过准确说也不能算是集群,只能说是主备。并且官方已经不推荐这种方式。
(2) 我没有测试过一旦主节点宕机不确定从节点能否自动接替。 -
主机配置/opt/mongodb/master-slave/master/mongodb.cfg
dbpath=/opt/mongodb/master-slave/master/data logpath=/opt/mongodb/master-slave/master/logs/mongodb.log logappend=true fork=true bind_ip=47.107.182.164 port=27001 master=true source=47.107.182.164:27002
-
从机配置/opt/mongodb/master-slave/slave/mongodb.cfg
dbpath=/opt/mongodb/master-slave/slave/data logpath=/opt/mongodb/master-slave/slave/logs/mongodb.log logappend=true fork=true bind_ip=47.107.182.164 port=27002 slave=true source=47.107.182.164:27001
-
启动服务
./mongod --config mongodb.cfg #主节点 ./mongod --config mongodb.cfg #从节点
-
连接测试
mongo --host 47.107.182.164 --port 27001 #客户端连接主节点 mongo --host 47.107.182.164 --port 27002 #客户端从节点
MongoDB 高可用方案-MongoDB 副本集搭建(Replica Set)
-
简介
(1) 简单来说就是集群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和主节点一致。
(2) Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点。主备节点存储数据,仲裁节点不存储数据。客户端同时连接主节点与备节点,不连接仲裁节点。
(3) 默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务。但是可以通过设置使备节点提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做Read Preference Modes,同时Java 客户端提供了简单的配置方式,可以不必直接对数据库进行操作。
(4) 仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别。我开始也不相信必须要有仲裁节点,但是自己也试过没仲裁节点的话,主节点挂了备节点还是备节点,所以咱们还是需要它的。 -
实际搭建
- 建立数据文件夹
#三个目录分别对应主,备,仲裁节点 mkdir -p /opt/mongodb/replset/master mkdir -p /opt/mongodb/replset/slaver mkdir -p /opt/mongodb/replset/arbiter
- 建立配置文件
(1) vi /opt/mongodb/replset/master/mongodb.cfg
(2) vi /opt/mongodb/replset/slave/mongodb.cfgdbpath=/opt/mongodb/replset/master/data logpath=/opt/mongodb/replset/master/logs/mongodb.log logappend=true replSet=shard002 bind_ip=47.107.182.164 port=27017 fork=true
(3) vi /opt/mongodb/replset/arbiter/mongodb.cfgdbpath=/opt/mongodb/replset/slave/data logpath=/opt/mongodb/replset/slave/logs/mongodb.log logappend=true replSet=shard002 bind_ip=120.78.181.181 port=27017 fork=true
dbpath=/opt/mongodb/replset/arbiter/data logpath=/opt/mongodb/replset/arbiter/logs/mongodb.log logappend=true replSet=shard002 bind_ip=112.74.170.31 port=27017 fork=true
- 建立数据文件夹
-
启动mongodb
monood -f /opt/mongodb/replset/master/mongodb.cfg #登录47.107.182.164 启动主节点 mongod -f /opt/mongodb/replset/slave/mongodb.cfg #登录120.78.181.181 启动从节点 mongod -f /opt/mongodb/replset/arbiter/mongodb.cfg #登录112.74.170.31 启动仲裁节点
-
配置主,备,仲裁节点
(1) 可以通过客户端连接mongodb,也可以直接在三个节点中选择一个连接mongodb。
(2) cfg 是相当于设置一个变量,可以是任意的名字,当然最好不要是mongodb 的关键字,conf,config 都可以
(3) 最外层的_id 表示replica set 的名字,members 里包含的是所有节点的地址以及优先级。优先级最高的即成为主节点,即的47.107.182.164:27017。
(4) 对于仲裁节点,需要有个特别的配置——arbiterOnly:true
(5) 配置的生效时间根据不同的机器配置会有长有短,配置不错的话基本上十几秒内就能生效,有的配置需要一两分钟。
(6) 登录MongoDB执行如下命令:mongo 47.107.182.164:27017 #ip 和port 是某个节点的地址 use admin cfg={_id:"shard002",members[{_id:0,host:'47.107.182.164:27017',priority:9},{_id:1,host:'120.78.181.181:27017',priority:1},{_id:2,host:'112.74.170.31:27017',arbiterOnly:true}]}; rs.initiate(cfg) #使配置生效
(7) 如果生效了,执行rs.status()命令会看到如下信息
(8) 如果配置正在生效,其中会包含如下信息:
-
测试
(1) 往主节点插入数据,能从备节点查到之前插入的数据(查询备节点可能会遇到某个问题,可以自己去网上查看)。
(2) 停掉主节点,备节点能变成主节点提供服务。
(3) 恢复主节点,备节点也能恢复其备的角色,而不是继续充当主的角色。
(4) 二和三都可以通过rs.status()命令实时查看集群的变化
MongoDB 高可用方案-MongoDB 数据分片搭建(Sharding)
-
简介
和Replica Set 类似,都需要一个仲裁节点,但是Sharding 还需要配置节点和路由节点。 -
实际搭建
-
配置数据节点
mkdir -p /opt/mongodb/shard/replset/replica1/data
mkdir -p /opt/mongodb/shard/replset/replica1/logs
mkdir -p /opt/mongodb/shard/replset/replica2/data
mkdir -p /opt/mongodb/shard/replset/replica2/logs
mkdir -p /opt/mongodb/shard/replset/replica3/data
mkdir -p /opt/mongodb/shard/replset/replica3/logs -
制作数据节点配置文件
(1) vi /opt/mongodb/shard/replset/replica1/mongodb.cfgdbpath=/opt/mongodb/shard/replset/replica1/data logpath=/opt/mongodb/shard/replset/replica1/logs/mongodb.log logappend=true fork=true bind_ip=47.107.182.164 port=27001 replSet=shard001 shardsvr=true
(2) vi /opt/mongodb/shard/replset/replica2/mongodb.cfg
dbpath=/opt/mongodb/shard/replset/replica2/data logpath=/opt/mongodb/shard/replset/replica2/logs/mongodb.log logappend=true fork=true bind_ip=47.107.182.164 port=27002 replSet=shard001 shardsvr=true
(3) vi /opt/mongodb/shard/replset/replica3/mongodb.cfg
dbpath=/opt/mongodb/shard/replset/replica3/data logpath=/opt/mongodb/shard/replset/replica3/logs/mongodb.log logappend=true fork=true bind_ip=47.107.182.164 port=27003 replSet=shard001 shardsvr=true
-
启动数据节点
mongod -f /opt/mongodb/shard/replset/replica1/mongodb.cfg #47.107.182.164:27001 mongod -f /opt/mongodb/shard/replset/replica2/mongodb.cfg #47.107.182.164:27002 mongod -f /opt/mongodb/shard/replset/replica3/mongodb.cfg #47.107.182.164:27003
-
使数据节点集群生效
mongo 47.107.182.164:27001 #ip 和port 是某个节点的地址 cfg={_id:"shard001",members[{_id:0,host:'47.107.182.164:27001'},{_id:1,host:'47.107.182.164:27002'},{_id:2,host:'47.107.182.164:27003'}]}; rs.initiate(cfg) #使配置生效
-
配置configsvr(配置节点)
mkdir -p /opt/mongodb/shard/configsvr/config1/data mkdir -p /opt/mongodb/shard/configsvr/config1/logs mkdir -p /opt/mongodb/shard/configsvr/config2/data mkdir -p /opt/mongodb/shard/configsvr/config2/logs mkdir -p /opt/mongodb/shard/configsvr/config3/data mkdir -p /opt/mongodb/shard/configsvr/config3/logs
-
制作配置节点配置文件
(1) /opt/mongodb/shard/configsvr/config1/mongodb.cfgdbpath=/opt/mongodb/shard/configsvr/config1/data configsvr=true port=28001 fork=true logpath=/opt/mongodb/shard/configsvr/config1/logs/mongodb.log replSet=configrs logappend=true bind_ip=47.107.182.164
(2) /opt/mongodb/shard/configsvr/config2/mongodb.cfg
dbpath=/opt/mongodb/shard/configsvr/config2/data configsvr=true port=28002 fork=true logpath=/opt/mongodb/shard/configsvr/config2/logs/mongodb.log replSet=configrs logappend=true bind_ip=47.107.182.164
(3) /opt/mongodb/shard/configsvr/config3/mongodb.cfg
dbpath=/opt/mongodb/shard/configsvr/config3/data configsvr=true port=28003 fork=true logpath=/opt/mongodb/shard/configsvr/config3/logs/mongodb.log replSet=configrs logappend=true bind_ip=47.107.182.164
-
启动configsvr 节点
mongod -f /opt/mongodb/shard/configsvr/config1/mongodb.cfg #47.107.182.164:28001 mongod -f /opt/mongodb/shard/configsvr/config2/mongodb.cfg #47.107.182.164:28002 mongod -f /opt/mongodb/shard/configsvr/config3/mongodb.cfg #47.107.182.164:28003
-
使configsvr 节点集群生效
mongo 47.107.182.164:28001 #ip 和port 是某个节点的地址 use admin #先切换到admin cfg={_id:"configrs",members:[{_id:0,host:'47.107.182.164:28001'},{_id:1,host:'47.107.182.164:28002'},{_id:2,host:'47.107.182.164:28003'}]}; rs.initiate(cfg) #使配置生效
-
配置路由节点
(1) 配置log目录mkdir -p /opt/mongodb/shard/routesvr/logs #注意:路由节点没有data 文件夹
(2) 制作路由节点配置文件
vi /opt/mongodb/shard/routesvr/mongodb.cfg configdb=configrs/47.107.182.164:28001,47.107.182.164:28002,47.107.182.164:28003//配置节点 port=30000 fork=true logpath=/opt/mongodb/shard/routesvr/logs/mongodb.log logappend=true bind_ip=47.107.182.164
-
启动路由节点
./mongos -f /opt/mongodb/shard/routesvr/mongodb.cfg #47.107.182.164:30000
一般来说一个数据节点对应一个配置节点,仲裁节点则不需要对应的配置节点。注意在启动路由节点时,要将配置节点地址写入到启动命令里。
-
配置Sharding
mongo 47.107.182.164:30000 #这里必须连接路由节点 sh.addShard("shard001/47.107.182.164:27001"); sh.addShard("shard002/47.107.182.164:27017"); #shard001、shard002 表示replica set 的名字当把主节点添加到shard 以后,会自动找到set 里的主,备,决策节点 use testdb sh.enableSharding("testdb") #对需要进行Sharding 的数据库进行配置 #对需要Sharding 的Collection 进行配置,testcon 即为Collection 的名字。另外还有key,比较关键,对于查询效率会有很大的影响。 sh.shardCollection("testdb.testcon",{"name":”hashed”}) db.collection.status()
-
-
以上只是最简单的搭建方式,其中某些配置仍然使用的是默认配置。如果设置不当,会导致效率异常低下,所以建议大家多看看官方文档再进行默认配置的修改。
以上三种集群搭建方式首选Replica Set,只有真的是大数据,Sharding 才能显现威力,毕竟备节点同步数据是需要时间的。Sharding 可以将多片数据集中到路由节点上进行一些对比,然后将数据返回给客户端,但是效率还是比较低的说。