1、mongodb简介
1)MongoDB 更类似 MySQL,支持字段索引、游标操作,其优势在于查询功能比较强大,擅长查询 JSON 数据, 能存储海量数据,但是不支持事务。
2)MySQL 在大数据量时效率显著下降,MongoDB 更多时候作为关系数据库的一种替代。
3)Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它 支持多种类型的数据结构,如 字符串(strings), 散列(hashes),列表(lists), 集合(sets), 有序集 合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务 (transactions) 和不同级别的 磁盘持久化(persistence),并通过 Redis哨兵(Sentinel)和自动 分区 (Cluster)提供高可用性(high availability)
2、Redis和MongoDB的区别
之前也用过redis,当时是用来存储一些热数据,量也不大,但是操作很频繁。现在项目中用的是MongoDB,目前是百万级的数据,将来会有千万级、亿级。
就Redis和MongoDB来说,大家一般称之为Redis缓存、MongoDB数据库。这也是有道有理有根据的:
Redis主要把数据存储在内存中,其“缓存”的性质远大于其“数据存储“的性质,其中数据的增删改查也只是像变量操作一样简单;
MongoDB却是一个“存储数据”的系统,增删改查可以添加很多where条件,就像SQL数据库一样灵活
1)内存管理机制
Redis 数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的 LRU 算法删除数据。 MongoDB 数据存在内存,由 linux系统 mmap 实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。
2)支持的数据结构
Redis 支持的数据结构丰富,包括hash、set、list等。 MongoDB 数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。
3)数据量和性能:
当物理内存够用的时候,redis>mongodb>mysql 当物理内存不够用的时候,redis和mongodb都会使用虚拟内存。 实际上如果redis要开始虚拟内存,那很明显要么加内存条,要么你换个数据库了。 但是,mongodb不一样,只要,业务上能保证,冷热数据的读写比,使得热数据在物理内存中,mmap的交换较少。 mongodb还是能够保证性能。
4)性能
mongodb依赖内存,TPS较高;Redis依赖内存,TPS非常高。性能上Redis优于MongoDB。
5)可靠性
mongodb从1.8版本后,采用binlog方式(MySQL同样采用该方式)支持持久化,增加可靠性;Redis依赖快照进行持久化;AOF增强可靠性;增强可靠性的同时,影响访问性能。可靠性上MongoDB优于Redis。
6)数据分析
mongodb内置数据分析功能(mapreduce);而Redis不支持。
7)事务支持情况
Redis 事务支持比较弱,只能保证事务中的每个操作连续执行;mongodb不支持事务。
8)集群
MongoDB 集群技术比较成熟,Redis从3.0开始支持集群。
3、MongoDB命令
1)连接:
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
2)查看 / 创建 / 删除 数据库
show dbs // 查看所有数据库 use DATABASE_NAME // 创建数据库 use DATABASE_NAME; db.dropDatabase() // 切换到当前数据库,并执行删除命令
3)查看 / 创建 / 删除 集合
show colletctions // 查看集合
db.createCollection(name, options) // 创建集合【option:capped-true:固定大小的集合,size:集合的字节数 max:集合的最大文档数,在插入文档时,先检查size,再检查max】
db.name.drop() // 删除集合
4)插入文档
db.name.insert({}) // 插入数据 db.name.insertOne({}) // 插入单条数据 db.name.insertMary([{}, {}]) // 插入多条数据 db.name.replaceOne({}) // _id存在则更新,否则是新增
5)更新文档
db.name.update({query}, {update}, {option}) // multi:更新多条,默认一条,update:操作符:$set 更新 $inc 递增
6)删除文档
db.name.remove({query}, {option}) // justOne:是否只删除一条,默认删除所有
7)查询文档
db.name.find({query}, {projection}) // 查询文档,projection 查询字段 db.name.findOne({query}, {projection}) // 查询文档,只返回第一条 db.name.find().pretty() // 查询文档-格式化
8)条件操作符
{<key>:<value>} // 等于 {<key>:{$lt:<value>}} // $lt 小于 $lte 小于或等于 $gt 大于 $gte 大于或等于 $ne 不等于 {key1:value1, key2:value2} AND条件 {$or: [{key1:value1}, {key2:value2}]} OR条件
9)$type 操作符
{<key>:{$type: <type>}} 1: Double 2: String 3: Object| 4: Array 5: Binary data 7: Object_id 8: Boolean 9: Date 10: Null 11: Regular Expression 13: Javascript 14: Symbol 15: Javascript(with scope) 16: 32-bit integer 17: Timestamp 18: 64-bit integer 255: Min key 127: Max key
10)limit 与 skip 方法
db.name.find().limit(number) // number 限制的数量 db.name.find().skip(number) // number 跳过的记录数
11)sort 排序
db.name.find().sort({<key>: 1}) // 按照key字段排序,1为升序排列 -1为降序排列
12)建立索引:索引存储在一个易于遍历读取的数据集合中
db.name.createIndex({<key>: 1}, options) // 以key字段建立索引,1为升序建立索引,可多个字段建立复合索引 // options:background-是否以后台形式建立索引,默认false; unique-唯一索引; name-索引名称 expireAfterSeconds-设定集合的生存时间 db.name.getIndexes() // 获取索引集合 db.name.totalIndexSize() // 获取集合索引大小 db.name.dropIndexs() // 删除所有索引 db.name.dropIndex("索引名称") // 删除单个索引
13)聚合:主要用于处理数据(如统计、平均值),并返回计算后的结果
db.name.aggregate(<operation>) 分组并计算:{[{$group: {"_id": "$字段", <显示名称>: {<计算方法>: {$字段}}}}]} // $sum-计算总和 $avg-计算平均值 $min-最小值 $max-最大值 $push-将值加入新数组 $addToSet-将值加入新数组,会判断是否重复 $frist 获取第一个文档 $last 获取最后一个文档
管道的概念:
$project: 修改输入文档的结构。可以用来重命名、增加或者删除域,也可以用于创建计算结果以及嵌套文档 $match: 用于过滤数据,只输出符合条件的文档 $limit: 用于限制MongoDB聚合管道返回的文档数 $skip: 在聚合管道中跳过指定数量的文档,并返回余下的文档 $unwind: 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。 $group:将集合中的文档分组,可用于统计结果 $sort:将输入文档排序后输出 $geoNear:输出接近某一地理位置的有序文档
4、MongoDB复制(副本集)
MongoDB复制是讲数据同步到多个服务器的过程。
复制提供了数据的荣誉备份,并在多个服务器上存储数据副本,提高了数据的可用性,并保证了数据的安全性
复制还允许您从硬件故障和服务中断中恢复数据
复制的优点
1)保障数据的安全性
2)数据高可用性(24 * 7)
3)灾难恢复
4)无需停机维护(如备份,重建索引,压缩)
5)分布式读取数据
复制的原理
1)mongoDB的复制至少需要两个节点,其中一个是主节点,负责处理客户端请求,其余都是从节点,负责复制主节点上的数据
2)mongoDB各个节点常见的搭配方式为:一主一从、一主多从
3)主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致
副本集特征:
1)N个节点的集群
2)任何节点可作为主节点
3)所有写入操作都在主节点上
4)自动故障操作
5)自动恢复
5、MongoDB分片
在mongoDB里面存在另一种集群,就是分片技术,可以满足mongoDB数量大量增长的需求
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时候我们可以通过在多台机器分割数据,使得数据库系统能存储和处理更多的数据
为什么使用分片:
1)复制所有的写入操作到主节点
2)延迟的敏感数据会在主节点查询
3)单个副本集限制在12个节点
4)当请求量巨大时会出现内存不足
5)本地磁盘不足
6)垂直扩展价格昂贵
分片有三个主要组件:
1)Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障
2)Config Server:mongo实例,存储了整个ClusterMetadata,其中包括chunk信息
3)Query Routes:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用