1. MongoDB 是什么看完你就知道了
点击上方 蓝色字体 ,选择“置顶公众号”
优质文章,第一时间送达
链接 | blog.csdn.net/hayre/article/details/80628431
1.MongoDB是什么?用一句话总结
MongoDB是一款为web应用程序和互联网基础设施设计的数据库管理系统。没错MongoDB就是数据库,是Nosql类型的数据库。
(1)MongoDB提出的是文档、集合的概念,使用BSON(类JSON)作为其数据模型结构,其结构是面向对象的而不是二维表,存储一个用户在MongoDB中是这样子的。
使用这样的数据模型,使得MongoDB能在生产环境中提供高读写的能力,吞吐量较于mysql等SQL数据库大大增强。
(2)易伸缩,自动故障转移。易伸缩指的是提供了分片能力,能对数据集进行分片,数据的存储压力分摊给多台服务器。自动故障转移是副本集的概念,MongoDB能检测主节点是否存活,当失活时能自动提升从节点为主节点,达到故障转移。
(3)数据模型因为是面向对象的,所以可以表示丰富的、有层级的数据结构,比如博客系统中能把“评论”直接怼到“文章“的文档中,而不必像myqsl一样创建三张表来描述这样的关系。
3.主要特性
(1)文档数据类型
SQL类型的数据库是正规化的,可以通过主键或者外键的约束保证数据的完整性与唯一性,所以SQL类型的数据库常用于对数据完整性较高的系统。MongoDB在这一方面是不如SQL类型的数据库,且MongoDB没有固定的Schema,正因为MongoDB少了一些这样的约束条件,可以让数据的存储数据结构更灵活,存储速度更加快。 (2)即时查询能力
MongoDB保留了关系型数据库即时查询的能力,保留了索引(底层是基于B tree)的能力。这一点汲取了关系型数据库的优点,相比于同类型的NoSQL redis 并没有上述的能力。 (3)复制能力
MongoDB自身提供了副本集能将数据分布在多台机器上实现冗余,目的是可以提供自动故障转移、扩展读能力。 (4)速度与持久性
MongoDB的驱动实现一个写入语义 fire and forget ,即通过驱动调用写入时,可以立即得到返回得到成功的结果(即使是报错),这样让写入的速度更加快,当然会有一定的不安全性,完全依赖网络。
MongoDB提供了Journaling日志的概念,实际上像mysql的bin-log日志,当需要插入的时候会先往日志里面写入记录,再完成实际的数据操作,这样如果出现停电,进程突然中断的情况,可以保障数据不会错误,可以通过修复功能读取Journaling日志进行修复。
(5)数据扩展
MongoDB使用分片技术对数据进行扩展,MongoDB能自动分片、自动转移分片里面的数据块,让每一个服务器里面存储的数据都是一样大小。
MongoDB核心服务器主要是通过mongod程序启动的,而且在启动时不需对MongoDB使用的内存进行配置,因为其设计哲学是内存管理最好是交给操作系统,缺少内存配置是MongoDB的设计亮点,另外,还可通过mongos路由服务器使用分片功能。
MongoDB的主要客户端是可以交互的js shell 通过mongo启动,使用js shell能使用js直接与MongoDB进行交流,像使用sql语句查询mysql数据一样使用js语法查询MongoDB的数据,另外还提供了各种语言的驱动包,方便各种语言的接入。
mongomp和mongorestore,备份和恢复数据库的标准工具。输出BSON格式,迁移数据库。
mongoexport和mongoimport,用来导入导出JSON、CSV和TSV数据,数据需要支持多格式时有用。mongoimport还能用与大数据集的初始导入,但是在导入前顺便还要注意一下,为了能充分利用好mongoDB通常需要对数据模型做一些调整。
mongosniff,网络嗅探工具,用来观察发送到数据库的操作。基本就是把网络上传输的BSON转换为易于人们阅读的shell语句。
因此,可以总结得到,MongoDB结合键值存储和关系数据库的最好特性。因为简单,所以数据极快,而且相对容易伸缩还提供复杂查询机制的数据库。MongoDB需要跑在64位的服务器上面,且最好单独部署,因为是数据库,所以也需要对其进行热备、冷备处理。
因为本篇文章不是API手册,所有这里对shell的使用也是基础的介绍什么功能可以用什么语句,主要是为了展示使用MongoDB shell的方便性,如果需要知道具体的MongoDB shell语法可以查阅官方文档。
创建数据库并不是必须的操作,数据库与集合只有在第一次插入文档时才会被创建,与对数据的动态处理方式是一致的。简化并加速开发过程,而且有利于动态分配命名空间。如果担心数据库或集合被意外创建,可以开启严格模式。
以上的命令只是简单实例,假设如果你之前没有学习过任何数据库语法,同时开始学sql查询语法和MongoDB 查询语法,你会发现哪一个更简单呢?如果你使用的是java驱动去操作MongoDB,你会发现任何的查询都像Hibernate提供出来的查询方式一样,只要构建好一个查询条件对象,便能轻松查询(接下来会给出示例),博主之前熟悉ES6,所以入手MongoDB js shell完成没问题,也正因为这样简洁,完善的查询机制,深深的爱上了MongoDB。
使用java驱动链接MongoDB是一件非常简单的事情,简单的引用,简单的做增删改查。在使用完java驱动后我才发现spring 对MongoDB 的封装还不如官方自身提供出来的东西好用,下面简单的展示一下使用。
这里只举例了简单的链接与简单的MongoDB操作,可见其操作的容易性。使用驱动时是基于TCP套接字与MongoDB进行通信的,如果查询结果较多,恰好无法全部放进第一服务器中,将会向服务器发送一个getmore指令获取下一批查询结果。
插入数据到服务器时间,不会等待服务器的响应,驱动会假设写入是成功的,实际是使用客户端生成对象id,但是该行为可以通过配置配置,可以通过安全模式开启,安全模式可以校验服务器端插入的错误。
要清楚了解MongoDB的基本数据单元。在关系型数据库中有带列和行的数据表。而MongoDB数据的基本单元是BSON文档,在键值中有指向不定类型值的键,MongoDB拥有即时查询,但不支持联结操作,简单的键值存储只能根据单个键来获取值,不支持事务,但支持多种原子更新操作。
如读写比是怎样的,需要何种查询,数据是如何更新的,会不会存在什么并发问题,数据结构化的程度是要求高还是低。系统本身的需求决定mysql还是MongoDB。
在关于schema 的设计中要注意一些原则,比如:
数据库是集合的逻辑与物理分组,MongoDB没有提供创建数据库的语法,只有在插入集合时,数据库才开始建立。创建数据库后会在磁盘分配一组数据文件,所有集合、索引和数据库的其他元数据都保存在这些文件中,查阅数据库使用磁盘状态可通过。
集合是结构上或概念上相似得文档的容器,集合的名称可以包含数字、字母或 . 符号,但必须以字母或数字开头,完全。
限定集合名不能超过128个字符,实际上 . 符号在集合中很有用,能提供某种虚拟命名空间,这是一种组织上的原则,和其他集合是一视同仁的。在集合中可以使用。
其次是键值,在MongoDB里面所有的字符串都是UTF-8类型。数字类型包括double、int、long。日期类型都是UTC格式,所以在MongoDB里面看到的时间会比北京时间慢8小时。整个文档大小会限制在16m以内,因为这样可以防止创建难看的数据类型,且小文档可以提升性能,批量插入文档理想数字范围是10~200,大小不能超过16MB。
(2)解析查询时MongoDB通过最优计划选择一个索引进行查询,当没有最适合索引时,会先不同的使用各个索引进行查询,最终选出一个最优索引做查询
(3)如果有一个a-b的复合索引,那么仅针对a的索引是冗余的
(4)复合索引里的键的顺序是很重要的
(2)复合索引
(3)唯一性索引
(4)稀疏索引
如索引的字段会出现的值,或是大量文档都不包含被索引的键。
如果数据集很大时,构建索引将会花费很长的时间,且会影响程序性能,可通过
当使用 mongorestore 时会重新构建索引。当曾经执行过大规模的删除时,可使用
对索引进行压缩,重建。
(1)查阅慢查询日志
(2)分析慢查询
注意新版本的MongoDB 的explain方法是需要参数的,不然只显示普通的信息。
本节同样主要简单呈现MongoDB副本集搭建的简易性,与副本集的强壮性,监控容易性
提供主从复制能力,热备能力,故障转移能力
实际上MongoDB对副本集的操作跟mysql主从操作是差不多的,先看一下mysql的主从数据流动过程
而MongoDB主要依赖的日志文件是oplog
写操作先被记录下来,添加到主节点的oplog里。与此同时,所有从结点复制oplog。首先,查看自己oplog里最后一条的时间戳;其次,查询主节点oplog里所有大于此时间戳的条目;最后,把那些条目添加到自己的oplog里并应用到自己的库里。从节点使用长轮询立即应用来自主结点oplog的新条目。
当遇到以下情况,从节点会停止复制
local数据库保存了所有副本集元素据和oplog日志
可以使用以下命令查看复制情况
每个副本集成员每秒钟ping一次其他所有成员,可以通过rs.status看到节点上次的心跳检测时间戳和 健康 状况。
这个点没必要过多描述,但是有一个特殊场景,如果从节点和仲裁节点都被杀了,只剩下主节点,他会把自己降级成为从节点。
如果主节点的数据还没有写到从库,那么数据不能算提交,当该主节点变成从节点时,便会触发回滚,那些没写到从库的数据将会被删除,可以通过rollback子目录中的BSON文件恢复回滚的内容。
只能链接到主节点,如果链接到从节点的话,会被拒绝写入操作,但是如果没有使用安全模式,因为mongo的fire and forget 特性,会把拒绝写入的异常给吃掉。
(2)使用副本集方式链接
能根据写入的情况自动进行故障转移,但是当副本集进行新的选举时,还是会出现故障,如果不使用安全模式,依旧会出现写不进去,但现实成功的情况。
分片是数据库切分的一个概念实现,这里也是简单总结为什么要使用分片以及分片的原理,操作。
当数据量过大,索引和工作数据集占用的内存就会越来越多,所以需要通过分片负载来解决这个问题
(2)分片的核心操作
分片一个集合:分片是根据一个属性的范围进行划分的,MongoDB使用所谓的分片键让每个文档在这些范围里找到自己的位置
块:是位于一个分片中的一段连续的分片键范围,可以理解为若干个块组成分片,分片组成MongoDB的全部数据
(3)拆分与迁移
块的拆分:初始化时只有一个块,达到最大块尺寸64MB或100000个文档就会触发块的拆分。把原来的范围一分为二,这样就有了两个块,每个块都有相同数量的文档。
迁移:当分片中的数据大小不一时会产生迁移的动作,比如分片A的数据比较多,会将分片A里面的一些块转移到分片B里面去。分片集群通过在分片中移动块来实现均衡,是由名为均衡器的软件进程管理的,任务是确保数据在各个分片中保持均匀分布,当集群中拥有块最多的分片与拥有块最少分片的块差大于8时,均衡器就会发起一次均衡处理。
启动两个副本集、三个配置服务器、一个mongos进程
配置分片
(2)索引
分片集合只允许在_id字段和分片键上添加唯一性索引,其他地方不行,因为这需要在分片间进行通信,实施起来很复杂。
当创建分片时,会根据分片键创建一个索引。
(2)低效的分片键
(3)理想的分片键
根据不同的数据中心划分
(2)最低要求
(3)配置的注意事项
需要估计集群大小,可使用以下命令对现有集合进行分片处理
(4)备份分片集群
备份分片时需要停止均衡器
使用64位机器、32位机器会制约mongodb的内存,使其最大值为1.5GB
(2)cpu mongodb 只有当索引和工作集都可放入内存时,才会遇到CPU瓶颈,CPU在mongodb使用中的作用是用来检索数据,如果看到CPU使用饱和的情况,可以通过查询慢查询日志,排查是不是查询的问题导致的,如果是可以通过添加索引来解决问题
mongodb写入数据时会使用到CPU,但是mongodb写入时间一次只用到一个核,如果有频繁的写入行为,可以通过分片来解决这个问题 (3)内存
大内存是mongodb的保障,如果工作集大小超过内存,将会导致性能下降,因为这将会增加数据加载入内存的动作
(4)硬盘
mongodb默认每60s会与磁盘强制同步一次,称为后台刷新,会产生I/O操作。在重启时mongodb会将磁盘里面的数据加载至内存,高速磁盘将会减少同步的时间
(5)文件系统
使用ext4 和 xfs 文件系统
禁用最后访问时间
(6)文件描述符
linux 默认文件描述符是1024,需要大额度的提升这个额度
(7)时钟
mongodb各个节点服务器之间使用ntp服务器
启动时使用 - -bind_ip 命令
(2)身份验证
启动时使用 - -auth 命令
(3)副本集身份认证
使用keyFile,注意keyFile文件的权限必须是600,不然会启动不起来
搭建副本集至少需要两个节点,其中仲裁结点不需要有自己的服务器
(2)Journaling日志 写数据时会先写入日志,而此时的数据也不是直接写入硬盘,而是写入内存
但是Journaling日志会消耗内存,所以可以在主库上面关闭,在从库上面启动
可以单独为Journaling日志使用一块固态硬盘
在插入时,可以通过驱动确保Journaling插入后再反馈,但是会非常影响性能。
-vvvvv 选项(v越多,输出越详细)
db.runCommand({logrotare:1}) 开启滚动日志
(2)top
(3)db.currentOp
动态展示mongodb活动数据
占用当前mongodb监听端口往上1000号的端口
把数据库内容导出成BSON文件,而mongorestore能读取并还原这些文件
(2)mongorestore
把导出的BSON文件还原到数据库
(3)备份原始数据文件 可以这么做,但是,操作之前需要进行锁库处理 db.runCommand({fsync:1,lock:true}) db.$cmd.sys.unlock.findOne 请求解锁操作,但是数据库不会立刻解锁,需要使用 db.currentOp 验证。
db.runCommand({repairDatabase:1}) 修复单个数据库
修复就是根据Jourling文件读取和重写所有数据文件并重建各个索引 (2)压紧
压紧,会重写数据文件,并重建集合的全部索引,需要停机或者在从库上面运行,如果需要在主库上面运行,需要添加force参数 保证加写锁。
(2)为提升性能检查索引和查询
总的来说,扫描尽可能少的文档。
保证没有冗余的索引,冗余的索引会占用磁盘空间、消耗更多的内存,在每次写入时还需做更多工作
(3)添加内存
dataSize 数据大小 和 indexSize 索引大小,如果两者的和大于内存,那么将会影响性能。
storageSize超过dataSize 数据大小 两倍以上,就会因磁盘碎片而影响性能,需要压缩。
2. MongoDB 数据库
游戏服务器开发中,玩家的账号,背包,装备,物品,排名等数据都需要落地存储在数据库中。行业中主流的数据库当属mysql,优点是免费开源,从端游时代过渡过来的程序员,求稳保守的话大多数会选用mysql数据库做存储。但是游戏中要存储的数据表会经常改动,导致数据库的表会频繁更新改动表结构,如果游戏数据量达到千万级别,对所有的表刷新改动会是一项很恐怖的事情,期间如果再出错,运维跟开发人员估计全都GG。
为了应对方便扩展,提升读写速度,NoSQL数据库(非关系型数据库)诞生。在NoSQL中应用比较广泛的当属mongodb和redis,由于对开发者友好,方便快速开发迭代高可用复制集满足数据高可靠、服务高可用的需求,运维简单,故障自动切换可扩展分片集群海量数据存储被游戏服务器广泛应用。现在的项目《鹿鼎记》用redis做高速缓存角色列表信息数据。
3. 单机mongodb数据库怎么导入分片集群中
准备工作:在导入数据前,先配置好要分片的数据库及表。
不然导入完成后,发现数据库,表没有同步到另外一个集群。
我这里做了从原单机数据库数据导出后,再分片集群库中导入操作。
当设置了要分片的库,及表后,系统会自动帮你添加库及表。
设置完成后,就可以导入数据了。
use admin
db.runCommand({enablesharding:"ip"})
db.runCommand({shardcollection:"ip.ipaddress",key:{ip1:1}})
./mongorestore -h 192.168.20.11 --port 28000 -d ip /opt/backup/ip20141109/ip
./mongorestore -h 192.168.20.11 --port 28000 -d dmp /opt/backup/dmp/dmp
4. mongoDB分片集群
集群 》 片 》 块 》 文档
一个集群由多个分片组成,一个分片存储了多个块(逻辑上的数据分块),一个快包含了多个文档,文档不是最小的单位,文档存了一个个的字段,一个字段或者多个字段可以组成一个片键
片键决定数据可以分成多少块
配置表里存的数据分布范围是怎么定的?
数据在逻辑上被分成了4块,加入系统存的是公司用户信息,按照年龄来分,18-60,一个年龄一个分块,最大可以分43块,在把块分到多个分片上,但是容易造成22-25的用户数据显得特别大,导致了热点片的情况
片键不是连续的而是通过hash散列到不同的片区,解决了数据不均匀的情况,但是范围查询效率低,需要遍历全部的分片才能满足业务查询,用户的订单系统,按照下单用户id去做hash,这样不同用户的订单数据就会被均匀分到不同的分片,单查某个用户的订单数据是非常高效的,但是根据时间范围去查就要扫描全部分片
根据地域去划分
切割器:可以对某个源分片的数据按chunk去做切割
平衡器:
当某些分片数据不均匀的情况下,平衡器就发挥作用了,他会发出一个命令让切割器去需要移动的分片上去做数据切割,再把数据移动到数据少的分片上。具体的步骤如下:
平衡器向源分片发送moveChunk的命令
源分片收到命令后,会启动自己内部的一个moveChunk命令,如果在数据移动过程中有客户端发来读写请求的话,都会发送到源分片。(因为配置服务器上的元数据还没有改变)
目标片开始向源分片请求将要移动的数据块的文档,准备拷贝文档数据。
当目标分片接收到据块的最后一个文档后,目标分片会启动一个同步进程来检查,是否已经拷贝完全部的文档。
当同步完成后,目标分片会连接配置服务器,更新元数据列表中数据块的地址。
当目标分片完成元数据更新后,源分片就会删除原来的数据块.如果有新的数据块需要移动的话,可以继续进行移动。
配置服务器会通知monogs进程更新自己的映射表。
数据容量日益增长,访问性能降低
5. mongodb分片后怎么取数据
分片是MongoDB提供的一种机制,其可以将大型的集合分割保存到不同的服务器上。与其他的分区方案相比,MongoDB几乎能自动为我们完成所有事情。只要我们进行简单的配置,并告诉MongoDB要分配的数据,它就可以自动维护数据在不同服务器之间的平衡。同时根据需要增减服务器,MongoDB也会自动移动平移已有数据。
分片机制提供了如下三种优势
1. 对集群进行抽象,让集群“不可见”。
MongoDB自带了一个叫做mongos的专有路由进程。mongos就是掌握统一路口的路由器,其会将客户端发来的请求准确无误的路由到集群中的一个或者一组服务器上,同时会把接收到的响应拼装起来发回到客户端。
2.保证集群总是可读写。
MongoDB通过多种途径来确保集群的可用性和可靠性。将MongoDB的分片和复制功能结合使用,在确保数据分片到多台服务器的同时,也确保了每分数据都有相应的备份,这样就可以确保有服务器换掉时,其他的副本可以立即接替坏掉的部分继续工作。
3.使集群易于扩展。
当系统需要更多的空间和资源的时候,MongoDB使我们可以按需方便的扩充系统容量。
实现数据分割
分片(shard)是集群中存储集合数据子集的一台或者多台服务器。在生产环境中一个分片通常是一个副本集(replica set)。
片键(key),MongoDB以其作为依据来确定需要在不同分片服务器之间移动的数据。例如我们可以选择用户名(username)字段作为分片键,现有一用户名区间[“p”,”z”],那么wufengtinghai是属于这一区间的,那么数据最终会保存到与此区间对应的分片服务器上。
分配数据到分片服务器
分配数据到分片服务器可以使用不同的方式,了解不同的方式可以加深我们对MongoDB使用方式的理解。
一分片一区间
分配数据到分片最简单的方式莫过于一个区间一个分片。假设我们有四个分片存储用户的相关信息,则我们可能会得到如下的分片和区间的对应关系。
这种分片方式非常简单易懂,但是在一个大型繁忙的系统中却会带来许多的不便。假如大量的用户使用首字母在【“a”,”f”)中的名字来注册,这将会导致分片1比较大,因此需要将其一部分文档移动到分片2上,我们可以调整分片1对应区间【”a”,”c”),使分片2的区间变成【”c”,”n”)。
如果移动数据后,分片2因此过载怎么办?假设分片1和分片2各有500G数据,而分片3和分片4各自有300G数据。那么按照这个方案,最终需要一连串的复制,总共算下来需要移动400G数据,考虑到需要在集群的服务器之间移动这些数据,可见移动数据量之大。
如果需要新加分片服务器进行水平扩展呢?假设此时每个分片上都有了500G数据,那么我们现在需要将分片4上的400G数据移动到分片5,将分片3的300G数据移动到分片4,将分片2的200G数据移动到分片3,将分片1的100G数据移动到分片2,整整移动了1T的数据!
随着分片数量和数据量的增长,这种噩梦将会持续下去,因此MongoDB不会采用这种方式。
一分片多区间
如果我们采用一分片多区间的方式,我们可以将分片1上的数据划分为两个区间,【”a”,”d”)包含400G数据,【”d”,”f”)包含100G数据,同样我们也可以对分片2做类似的处理,得到区间【”f”,”j”)和【“j”,”n”)。现在我们只需要将分片1上的【”d”,”f”)数据移动到分片4,将分片2的【“j”,”n”)的数据移动到分片3。这样我们仅仅只需要移动200G数据。
如果要添加新分片,可以从每个分片顶端取100G数据并将其移动到新的分片上,这样仅仅只需要移动400G数据即可。
MongoDB就是利用这种方式,当一个分片的数据越来越大时,其会自动分割片键区间,并将分片的数据进行分割并移动到其他分片。
6. 更新频繁的MongoDB数据库 有什么优化建议
更新频繁的并不是mongodb的优势,建议使用缓存数据库和mongodb搭配使用,更新频繁的数据使用缓存存储,一定时间再同步到mongodb中。
7. 如何在mongodb上备份和恢复数据
在大数据时代,企业的应用带来了大量的数据,它们可能具有结构化、半结构化或非结构化的性质。此外,应用程序开发周期短和可用性强都是他们要考虑的关键问题。考虑到这些应用程序的要求,在下一代平台3应用程序中,企业必须超越传统的关系数据库(IaaS或基于云计算PaaS)。在NoSQL数据库中,像MongoDB现在就被采用了,同时又对这些下一代应用程序的企业进行了评估(如电子商务、内容管理等)。MongoDB提供了动态模式,通过自动分片易扩展、读写一致性和在内置中进行复制的功能。
MongoDB数据库具有本地复制的功能,同时满足可用性的需求。然而,数据保护要求可伸缩的时间点备份和恢复需要得到很好的解决。对于可靠的数据保护,企业需要备份和复制!没有时间点的备份,组织会由于人为的错误、逻辑混乱和其他操作的失败导致有丢失数据的风险。传统的备份解决方案是建立在关系数据库中,使用共享存储和ACID事务模型,来解决结构化平台2应用程序的要求而建的。不幸的是,他们不足以解决平台 3 应用程序和分布式的数据库(本地存储、 最终一致性和基础设施的弹性性质)的时间点备份要求。有几个备用的基于脚本的解决方案(例如地层等),企业正在使用填补数据来保护缩短差距,但这些解决方案充其量算是次优的。
手动脚本解决方案
这些解决方案利用本地MongoDB快照工具和脚本将数据传输到辅助存储。(通过 mongomp) 脚本自定义的每个 MongoDB 集群和需要业务作出了重大努力,以适应任何拓扑更改 (例如添加或删除节点到 MongoDB 数据库) 或扩大规模。此外,这些脚本不适应失败场景,比如失败的一个节点(一级或二级)或间歇性的网络问题。最后,恢复(“备份”)的最重要的价值是一个手动过程。因此,耗费时间(导致很高的应用程序停机时间),并包含脚本中的任何 bug 数据丢失风险。总的来说,这些解决方案工作在MongoDB环境中很小和一些允许在应用程序中丢失的数据。这些解决方案所面临的一些关键问题是:
对分片配置的企业备份解决方案的不足;
当快照被取时,数据库需要脱机;
在节点故障和其他基础设施故障下,备份和恢复都失败了;
恢复过程是手动的并且需要验证,从而增加恢复时间;
收集级的恢复需要耗时的手动恢复;
恢复与不同的测试/开发的拓扑(切分 → 分片)刷新是不可用的。
MongoDB支付备份和恢复(又名“MMS”)
MongoDB(公司)本身提供了一些备份MongoDB数据库的方法。企业可以选择从一个管理备份提供(MMS)运行在公共云,或如果他们支付 MongoDB 的客户,他们可能以部署本地备份服务为前提。除了成本过高,在公共云上管理备份服务存储的客户数据。对于部署 MongoDB 为前提,在 WAN 上备份数据传输可能无法为客户工作,并且海需要为客户保持他们对数据内部的敏感度。此外,还有重要的数据来限制每个碎片去使用这项服务。
使用MongoDB部署备份服务是有可能的,但部署和实施过于复杂。企业需要部署8台服务器,附加数据库(额外的许可证)和 6-9x存储容量。总的来说,部署备份服务是一个理论上的解决方案,带来了显着的CAPEX和OPEX投资:
部署多个数据库的复杂性;
额外的基础设施成本;
授权额外的MongoDB节点成本;
当节点失败时,带来备份失败的风险;
独立的MongoDB数据库备份基础设施。
实现企业客户的数据保护要求,进入了新兴的下一代分布式数据库的时代(键值、图形、文档库等),并且解决上述方案的局限性。Datos IO建造了产业界首次扩展数据保护软件产品,使平台3应用程序能部署到分布式和云数据库上,如MongoDB和Apache Cassandra。Datos IO解决方案是刚刚兴起的下一代应用程序,迎合了业主和DevOps的应用需求,并解决了部署和管理保护基础设施操作所带来的一切麻烦。最重要的是,它是一个可靠的和可扩展的解决方案,即使在使用节点失败的场景下,也会通过最小化恢复时间获得最优的性能。
8. mongodb分片结束,主片中数据重复
1、集合中的数据不会分片。
配置了shard1/shard2/shard3三个分片,但数据只会集中在集合所在的分片上。
2、数据插入效率低下。
采用for循环批量插入20万数据时,发现每秒只能插入100,200条,无法忍受的性能。
9. mongo php 操作 怎样更新一条数据
PHP操作MongoDB数据库的简单示例。
Mongodb的常用操作
参看手册,php官方的http://us2.php.net/manual/en/mongo.manual.php
也可以参看mongodb官方的教程。
一,Mognodb数据库连接
1)、默认格式
复制代码代码示例:
$m=newMongo();
//这里采用默认连接本机的27017端口,当然也可以连接远程主机如192.168.0.4:27017,如果端口是27017,端口可以省略。
2)、标准连接
$m=newMongo(“mongodb://${username}:${password}@localhost”);
实例:
复制代码代码示例:
$m=newMongo(“mongodb://127.0.0.1:27017/admin:admin”);
数据库的用户名和密码都是admin
数据库操作:
1)、插入数据:
复制代码代码示例:
<?php
//这里采用默认连接本机的27017端口,当然你也可以连接远程主机如192.168.0.4:27017
//如果端口是27017,端口可以省略
$m=newMongo("mongodb://127.0.0.1:27017/admin:admin");
//选择comedy数据库,如果以前没该数据库会自动创建,也可以用$m->selectDB("comedy");
$db=$m->comedy;
//选择comedy里面的collection集合,相当于RDBMS里面的表,也可以使用
$collection=$db->collection;
$db->selectCollection("collection");
/*********添加一个元素**************/
$obj=array("title"=>"php1","author"=>"BillWatterson");
//将$obj添加到$collection集合中
$collection->insert($obj);
/*********添加另一个元素**************/
$obj=array("title"=>"huaibei","online"=>true);
$collection->insert($obj);
//$query=array("title"=>"huaibei");
$query=array("_id"=>$obj['_id']);
$cursor=$collection->find($query);
//遍历所有集合中的文档
foreach($cursoras$obj){
echo$obj["title"]." ";
echo$obj["_id"]." ";
}
//断开MongoDB连接
$m->close();
2)、带条件的查询
查询title为huaibei的字段
1$query=array(”title”=>”huaibei”);
2$cursor=$collection->find($query);//在$collectio集合中查找满足$query的文档
常用的SQL转化为mongodb的条件
复制代码代码示例:
mysql:id=123
mongo:array(‘id’=>123)
mysql:namelink’%bar%’
mongo:array(‘name’=>newMongoRegex(‘/.*bar.*/i’))
mysql:whereid>10
mongo:array(‘id’=>array(‘$gt’=>10))
mysql:whereid>=10
mongo:array(‘id’=>array(‘$gte’=>10))
mysql:whereid<10
mongo:array(‘id’=>array(‘$lt’=>10))
mysql:whereid<=10
mongo:array(‘id’=>array(‘$lte’=>10))
mysql:whereid>1andid<10
mongo:array(‘id’=>array(‘$gt’=>1,’$lt’=>10))
mysql:whereid<>10
mongo:array(‘id’=>array(‘$ne’=>10))
mysql:whereidin(123)
mongo:array(‘id’=>array(‘$in’=>array(1,2,3)))
mysql:whereidnotin(123)
mongo:array(‘id’=>array(‘$nin’=>array(1,2,3)))
mysql:whereid=2orid=9
mongo:array(‘id’=>array(‘$or’=>array(array(‘id’=>2),array(‘id’=>9))))
mysql:orderbynameasc
mongo:array(‘sort’=>array(‘name’=>1))
mysql:orderbynamedesc
mongo:array(‘sort’=>array(‘name’=>-1))
mysql:limit0,2
mongo:array(‘limit’=>array(‘offset’=>0,’rows’=>2))
mysql:selectname,email
mongo:array(‘name’,'email’)
mysql:selectcount(name)
mongo:array(‘COUNT’)//注意:COUNT为大写
更详细的转换参考http://us2.php.net/manual/en/mongo.sqltomongo.php
注意事项:
查询时,每个Object插入时都会自动生成一个独特的_id,它相当于RDBMS中的主键,用于查询时非常方便(_id每一都不同,很像自动增加的id)
例如:
复制代码代码示例:
<?php
$param=array("name"=>"joe");
$collection->insert($param);
$joe=$collection->findOne(array("_id"=>$param['_id']));
print_R($joe);
$m->close();
返回结果:Array([_id]=>MongoIdObject([$id]=>4fd30e21870da83416000002)[name]=>joe)
更改字段值:
复制代码代码示例:
<?php
$sign=array("title"=>'php1');
$param=array("title"=>'php1','author'=>'test');
$joe=$collection->update($sign,$param);
删除一个数据库:
复制代码代码示例:
$m->dropDB(“comedy”);
列出所有可用数据库:
复制代码代码示例:
$m->listDBs();//无返回值
附,mongodb常用的数据库方法
MongoDB中有用的函数:
创建一个MongoDB对象
复制代码代码示例:
<?php
$mo=newMongo();
$db=newMongoDB($mo,’dbname’);//通过创建方式获得一个MongoDB对象
删除当前DB
复制代码代码示例:
<?php
$db=$mo->dbname;
$db->drop();
获得当前数据库名
复制代码代码示例:
<?php
$db=$mo->dbname;
$db->_tostring();
选择想要的collection:
复制代码代码示例:
A:
$mo=newMongo();
$coll=$mo->dbname->collname;//获得一个collection对象
B:
$db=$mo->selectDB(’dbname’);
$coll=$db->collname;
C:
$db=$mo->dbname;
$coll=$db->collname;
D:
$db=$mo->dbname;
$coll=$db->selectCollectoin(’collname’);//获得一个collection对象
插入数据(MongoCollection对象):
http://us.php.net/manual/en/mongocollection.insert.php
MongoCollection::insert(array$a,array$options)
array$a要插入的数组
array$options选项
safe是否返回操作结果信息
fsync是否直接插入到物理硬盘
例子:
复制代码代码示例:
$coll=$mo->db->foo;
$a=array(’a’=>’b’);
$options=array(’safe’=>true);
$rs=$coll->insert($a,$options);
$rs为一个array型的数组,包含操作信息
删除数据库中的记录(MongoCollection对象):
http://us.php.net/manual/en/mongocollection.remove.php
MongoCollection::remove(array$criteria,array$options)
array$criteria条件
array$options选项
safe是否返回操作结果
fsync是否是直接影响到物理硬盘
justOne是否只影响一条记录
例子:
复制代码代码示例:
$coll=$mo->db->coll;
$c=array(’a’=>1,’s’=>array(’$lt’=>100));
$options=array(’safe’=>true);
$rs=$coll->remove($c,$options);
$rs为一个array型的数组,包含操作信息
更新数据库中的记录(MongoCollection对象):
http://us.php.net/manual/en/mongocollection.update.php
MongoCollection::update(array$criceria,array$newobj,array$options)
array$criteria条件
array$newobj要更新的内容
array$options选项
safe是否返回操作结果
fsync是否是直接影响到物理硬盘
upsert是否没有匹配数据就添加一条新的
multiple是否影响所有符合条件的记录,默认只影响一条
例子:
复制代码代码示例:
$coll=$mo->db->coll;
$c=array(’a’=>1,’s’=>array(’$lt’=>100));
$newobj=array(’e’=>’f’,’x’=>’y’);
$options=array(’safe’=>true,’multiple’=>true);
$rs=$coll->remove($c,$newobj,$options);
$rs为一个array型的数组,包含操作信息
查询collection获得单条记录(MongoCollection类):
http://us.php.net/manual/en/mongocollection.findone.php
arrayMongoCollection::findOne(array$query,array$fields)
array$query条件
array$fields要获得的字段
例子:
复制代码代码示例:
$coll=$mo->db->coll;
$query=array(’s’=>array(’$lt’=>100));
$fields=array(’a’=>true,’b’=>true);
$rs=$coll->findOne($query,$fields);
如果有结果就返回一个array,如果没有结果就返回NULL
查询collection获得多条记录(MongoCollection类):
http://us.php.net/manual/en/mongocollection.find.php
MongoCursorMongoCollection::find(array$query,array$fields)
array$query条件
array$fields要获得的字段
例子:
复制代码代码示例:
$coll=$mo->db->coll;
$query=array(’s’=>array(’$lt’=>100));
$fields=array(’a’=>true,’b’=>true);
$cursor=$coll->find($query,$fields);
//排序
$cursor->sort(array(‘字段’=>-1));(-1倒序,1正序)
//跳过部分记录
$cursor->skip(100);跳过100行
//只显示部分记录
$cursor->limit(100);只显示100行
返回一个游标记录对象MongoCursor。
针对游标对象MongoCursor的操作(MongoCursor类):
http://us.php.net/manual/en/class.mongocursor.php
循环或结果记录:
复制代码代码示例:
$cursor=$coll->find($query,$fields);
while($cursor->hasNext()){
$r=$cursor->getNext();
var_mp($r);
}
或者
$cursor=$coll->find($query,$fields);
foreache($cursoras$k=>$v){
var_mp($v);
}
或者
$cursor=$coll->find($query,$fields);
$array=iterator_to_array($cursor);
10. MongoDB挑战传统数据库:非结构化数据库的迭新不容小觑
相比甲骨文中国在中国市场的裁员风波,同为数据库服务的MongoDB显得更为乐观。“MongoDB是中国开发者最喜欢用的一个数据库。”MongoDB全球渠道及亚太区销售高级副总裁Alan Chhabra带着一点自信和骄傲在媒体面前宣称。
中国企业的数字化转型正进入关键期,在打造开放、高效、灵活、共享的云计算基础设施的同时,数据库的更新换代也被提上了日程。
日前,非结构化数据库平台提供商MongoDB在上海举办用户大会,MongoDB全球渠道及亚太区销售高级副总裁Alan Chhabra接受了亿欧企业服务频道的采访, 并针对去年修改开源协议,在SSPL的不同许可机制下授权服务器软件的争议以及其他疑问作出回应。
数据库的本质是解决数据的存储和管理问题。 Alan Chhabra表示,对企业发展具有战略意义的数据库正在催生巨大的市场。
在这些潜力颇大的数据库中,市场上目前存在着的是关系型的传统数据库和以Mongo DB为代表的非关联式新型数据库。传统数据库比较典型的是甲骨文旗下的Oracle数据库、IBM推出的大数据平台Hadoop和Stream Computing、微软的SQL Server、SAP以及EMC Greenplum。 他们的主要差别在于数据库的结构化和非结构化。
结构化的数据是指可以使用关系型数据库表示和存储,表现为二维形式的数据,存储和排列很有规律,这对查询和修改等操作很有帮助,但扩展性和灵活性欠佳。 非结构化数据库就是各种文档、图片、视频/音频等没有固定结构的数据,一般直接整体进行存储为二进制的数据格式。 目前涵盖分布式数据库、图数据库、流数据库、时空数据库和众包数据库等多个领域。
MongoDB是文档型的非结构化新型数据库,Alan Chhabra表示, 与传统数据库相比,更能满足用户数据存储量大、计算灵活的需求。“在某些客户某些案例上,我们已经取代了传统数据库,比如甲骨文。”
当前, 软件对于商业模式的改变、开发人员地位的提高,以及企业向云端迁移的趋势 都让数据服务公司的发展得到了助力。但从毕马威会计事务所对首席信息官的调查结果来看, 88%的首席信息官认为他们未能从数字化战略中充分获益;82%的首席信息官认为其所在机构在利用技术推动业务发展方面并非“卓有成效”。 也就是说, 大多数公司的数字化战略是以失败告终的。
在此背景下,更加灵活、性能更加强大的新型数据库在一些领域获得了试验田丰收,并且可以看到,随着客户数据需求的繁杂程度的日益增加,传统数据库也在自我革新,以迎头赶上数据浪潮的大变革。
MongoDB成立于2007年,2017年在纳斯达克上市。最初,MongoDB是一项面向技术爱好者的技术,如今已成为一项企业级的业务关键技术。通过不断开发数据库即服务(Database-as-a-Service)产品,积极拥抱云计算,MongoDB在过去十年里,为开发人员提供了处理数据的方法。正因如此,它也成了企业数字化转型战略的一个关键部分。
MongoDB提供的产品主要包括MongoDB云服务MongoDB Atlas、MongoDB Mobile、MongoDB企业版和MongoDB Stitch等十余个相关产品。Alan Chhabra表示,产品包括了 开源版、付费版和云版。
2018 年 10 月,MongoDB宣布其开源许可证将从GNU AGPLv3切换到SSPL,新许可证将适用于新版本的MongoDB Community Server以及打过补丁的旧版本,这一举动引发了行业热议。基于GNU AGPLv3协议,企业可以将MongoDB作为公共服务但这需要企业开源自己的软件或是获得MongoDB的商业授权,事实却是MongoDB发现许多企业正在违反协议“疯狂试探”甚至已经违反协议。 SSPL( Server Side Public License)顾名思义,要求使用者必须得到服务器端公共许可证,这一协议会进一步约束商业公司使用MongoDB服务。
Alan Chhabra向亿欧解释, SSPL 针对的是提供MongoDB托管服务的云服务厂商。 也就是说,如果不是云服务厂商,没有公然售卖MongoDB产品,而只是作为应用后台数据库来使用的话,那么无论你是电商、物联网、金融、社交、 游戏 、移动应用等等,一概都不会有任何影响。 “MongoDB的宗旨还是为了始终支持并保护创新开放。”
但此开源协议的修改明显带来了市场用户的“掉粉”,比如Linux 社区的接连“弃用”,以及AWS 、IBM、微软推出了兼容MongoDB的相关产品来服务用户。
数据库开源的商业变现与创新形成的矛盾,目前似乎还尚未找到解决方案。
Alan Chhabra在大会上也透露了MongoDB的未来计划, 即将基于智能运营数据平台和下一代基础架构、文化、方法论和安全,推动原有系统的现代化、数据即服务、云数据策略、业务敏捷性,进而帮助客户实现以数据驱动的数字化转型。
针对MongoDB在中国的发展情况, Alan Chhabra表示,公司将以创新立足,持续引领数据库技术发展潮流,与合作伙伴携手助力中国企业的数字化转型。
MongoDB北亚区副总裁苏玉龙认为:“中国是数据大国,而数据就是未来的石油。如何利用好数据,让数据石油助力中国企业腾飞是MongoDB希望在中国达成的事情。随着中国企业数字化转型逐渐走向深入,MongoDB数据库的价值得到不断释放。”
本文作者龚晨霞,微信Gcx847076575,欢迎关注企业服务和产业互联网的朋友加微信交流。