当前位置: 首页 > 编程日记 > 正文

Mongo、Redis、Memcached对比及知识总结

存储原理(持久化)

  • Mongo
    Mongo的数据将会保存在底层文件系统,因此存储容量远大于redis和memcached。一个database中所有的collections以及索引信息会分散存储在多个数据文件中,即mongodb并没有像SQL数据库那样,每个表的数据、索引分别存储;数据分块的单位为extent(范围,区域),即一个data file中有多个extents组成,extent中可以保存collection数据或者indexes数据,一个extent只能保存同一个collection数据,不同的collections数据分布在不同的extents中,indexes数据也保存在各自的extents中;最终,一个collection有一个或者多个extents构成,最小size为8K,最大可以为2G,依次增大;它们分散在多个data files中。对于一个data file而言,可能包含多个collection的数据,即有多个不同collections的extents、index extents混合构成。每个extent包含多条documents(或者index entries),每个extent的大小可能不相等,但一个extent不会跨越2个data files。

clipboard.png

  • Redis
    1、Redis的数据存储在内存中,同时可以通过两种存储机制,将数据持久化到磁盘。
    (1)Snapshot工作原理: 是将数据先存储在内存,然后当数据累计达到某些设定的伐值的时候,就会触发一次DUMP操作,将变化的数据一次性写入数据文件(RDB文件)
    (2)AOF 工作原理: 是将数据也是先存在内存,但是固定时候会使用调用fsync来完成对本次写操作的日志记录,这个日志揭露文件其实是一个基于Redis网络交互协议的文本文件。AOF调用fsync也不是说全部都是无阻塞的,在某些系统上可能出现fsync阻塞进程的情况,对于这种情况可以通过配置修改,但默认情况不要修改。AOF最关键的配置就是关于调用fsync追加日志文件的频率,有两种预设频率,always每次记录进来都添加,everysecond 每秒添加一次。当redis重启时,将会读取AOF文件进行“重放”以恢复到redis关闭前的最后时刻。
    (3)两种存储原理比较:

     a.性能Snapshot方式的性能是要明显高于AOF方式的,原因有两点:采用2进制方式存储数据,数据文件比较小,加载快速。存储的时候是按照配置中的save策略来存储,每次都是聚合很多数据批量存储,写入的效率很好,而AOF则一般都是工作在实时存储或者准实时模式下。相对来说存储的频率高,效率却偏低。b.数据安全AOF数据安全性高于Snapshot存储,原因:Snapshot存储是基于累计批量的思想,也就是说在允许的情况下,累计的数据越多那么写入效率也就越高,但数据的累计是靠时间的积累完成的,那么如果在长时间数据不写入RDB,但Redis又遇到了崩溃,那么没有写入的数据就无法恢复了,但是AOF方式偏偏相反,根据AOF配置的存储频率的策略可以做到最少的数据丢失和较高的数据恢复能力。
    
  • Memcached
    1、Memcached不支持内存数据的持久化操作,所以的数据都以in-momory的形成存储。

数据类型:

  • Mongo
    1、字符串、整型、布尔型、双进度浮点型...具体参照:http://www.yiibai.com/mongodb...
  • Redis
    1、除了简单的key-value数据类型,同时还提供了list、hash、set、zset等数据结构的存储
  • Memcached
    1、Memcached使用key-value形式存储和访问数据

网络IO模型

  • Mongo
    1、多线程,同步 IO 模型。
    clipboard.png
    由主线程进行 accept 连接,然后针对每一个连接创建一个线程进行处理,「thread per connection」这种模型:
    (1)不适合短连接服务,创建/删除线程的开销是巨大的,体现在创建线程时间和至少1MB 内存的使用。
    (2)伸缩性受到线程数的限制,200+线程数的调度对 OS 也是不小的负担。另外随着线程数的增加, 由于 mongo 本身业务的特性,对数据处理的并发度并不高,DB锁和全局的原子操作造成的 context-switch 也是急剧上升,性能反而下降,频繁的线程切换对于 cache 也不友好。
  • Redis
    1、Redis使用 单线程的IO复用模型 ,自己封装了一个简单的Ae_Event事件处理框架,主要实现了epoll、kqueue、kvport和select,对于单存只有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型不能发挥多核CPU的优势,会严重影响整体吞吐率,因为在CPU的计算的过程中,整个IO调度是被阻塞的,因此 Redis不适合用于计算。
  • Memcached
    1、Memcached是 多线程、非阻塞IO复用 的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe传递给worker线程进行读写IO,网络层使用libevent封装的事件库,多线程模型可以发挥CPU多核作用,但是引入了cache coherency(缓存一致性)和锁的问题,比如:Memcached最常用的stats命令,实际Memcached所有操作都要对这个全局变量加锁、进行技术工作等,带来了性能损耗。(缓存的一致性就是指缓存中的数据是否和目标存储中的数据是一样的,也就是说缓存中已经修改得数据是否已经保存到了物理存储中,物理存储中已经被修改得内容,是否与缓存的内容是一样的。这就是一致性的概念。)

内存管理机制

  • Redis
    1、Redis的内存管理主要通过源码中的zmalloc.h和zmalloc.c两个文件来实现。Redis为了方便内存的管理,在分配了一块内存后,会将这块内存的大小存入内存块的头部。如下图所示,real_ptr是Redis调用malloc函数返回的指针,Redis将内存块的大小size存入头部(size所占据的大小是已知的,为size_t类型的长度),然后返回ret_ptr。当需要释放内存的时候,ret_ptr别传给内存管理程序,通过ret_ptr可以很容易计算出real_ptr的值,然后将real_ptr传给free释放掉。

    clipboard.png

    2、在Redis中,并不是所有的数组都一直存储在内存中的。这是和Memcached相比最大的一个区别。当物理内存用完的时候,Redis可以将一些很久没用到的value交换到磁盘(注:这里用到的是Redis的Virtual Memory技术,Redis2.4版本之后已经不提倡使用了)。Redis只会缓存所有key的信息,如果Redis发现内存的使用量超过了某个阈值,将触发swap操作。swap操作根据规则计算出哪些key对应的value需要swap到磁盘,然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保存超过其机器物理内存大小的数据。当然,机器本身的内存必须要能够保存所有的key,毕竟这部分数据是不会被swap到磁盘的。同时由于Redis将内存中的数据swap到磁盘的时候,提供服务的主线程和进行swap的子线程会共享这部分内存,所有如果需要更新swap的数据,Redis将阻塞这个操作,直到子线程完成swap之后才可以进行修改。当从Redis中读取数据的时候,如果读取的key的value不在内存中,那么Redis需要从swap文件中加载对应的数据,然后再返回给client,这里就存在一个I/O线程池的问题。在默认情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会执行相应的操作。这种策略在client数量较小,进行批量操作的时候比较合适。但是如果Redis应用在一个大型的网站应用中,这显示是无法满足大并发的情况的。所以Redis允许我们设置I/O线程池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。

  • Memcached
    1、Memcached默认使用Slab Allocation机制来管理内存,它的主要思想是 按照预先规定的大小,将分配的内存分割成特定长度的块,以存储相应长度的key-value数据记录,以完全解决内存碎片的问题。Slab Allocation机制只为存储外部数据而设计,也就是说所有的key-value数据都存储在slab allocation系统里面,但是Memcached的其他内存请求则是通过普通的malloc/free来申请,因为这些请求的数量和频率决定了它们不会对整个系统的性能造成影响。
    2、slab allocation机制的原理比较简单,如下图所示,它首先从操作系统申请一大块内存,并将其分割成各种尺寸的chunk(块),并把尺寸相同的chunk分成一组组slab class。其中,chunk就是用来存储key-value的最小单位。每个slab class的大小,可以在Memcached启动的时候通过制定growth factor来控制。
    clipboard.png

    3、当Memcached接收到客户端发过来的数据时,会根据收到数据的大小选择一个最合适的slab class,然后通过查询Memcached保存着的该slab class内空闲chunk的列表,就可以找到一个用于存储数据的chunk。当一条数据记录过期或者丢弃时,该记录所占用的chunk就可以被回收,重新添加到空闲列表中。
    4、从以上过程中可以看到,Memcached的内存管理效率高,并且不会造成内存碎片,但是它最大的不足是会造成空间浪费。因为每个chunk都分配了特定长度的内存空间,所以变长数据无法利用这些空间。如下图所示,将100字节的数据缓存到128字节的chunk中,剩余的28个字节就被浪费掉了。
    clipboard.png

集群管理

  • Mongo
    1、Replica Set:中文翻译叫做副本集,就是集群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和主节点一致。如下图:
    clipboard.png
    2、Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点。主备节点存储数据,仲裁节点不存储数据。客户端同时连接主节点与备节点,不连接仲裁节点。
    3、默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务。但是可以通过设置使备节点提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做Read Preference Modes,同时Java客户端提供了简单的配置方式,可以不必直接对数据库进行操作。
    4、仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别(由备用节点提升为主节点)。仲裁节点是必须的。详见:http://blog.csdn.net/luonanqi...
  • Redis
    1、相比Memcached只能采用客户端实现分布式存储,Redis更偏向在服务端构建分布式存储。新版本的Redis已经支持分布式存储功能。Redis Cluster是一个实现了分布式并且允许单点故障的Redis高级版本,它没有中心节点,具有线性可伸缩的功能。Redis Cluster的分布式存储架构,节点与节点之间通过二进制协议进行通讯,节点与客户端之间通过ascii协议通讯。在数据的放置策略上,Redis Cluster将整个key的数值域划分成16384(2^14)个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说Redis Cluster支持的最大节点数是16384。
    2、为了保证单点故障下得数据可用性,Redis Cluster引入了Master节点和Slave节点。在Redis Cluster中,每个Master节点都会对应2个用于冗余的Slave节点。这样在整个集群中,任意2个节点的宕机都不会导致数据的不可用。当Master节点下线后,集群会自动选择一个Slave节点成为新的Master节点。
  • Memcached
    1、Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果数据超过了单台机器的物理内存大小,那么就需要构建集群来扩展存储能力。
    2、Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。

应用场景

  • Memcached及Redis
    1、相对memcached来说,需要保证数据不丢失的话,选择Redis。
    2、当然,大部分情况来说,选择Redis是一个更好的选择,因为它更强大、更受欢迎,并且比Memcached有更多的支持者。Memcached只是Redis功能中的一小部分。所以对于新项目来说,选择Redis。
  • Mongo
    1、Mongo的使用和上面两个数据库是不冲突的,这篇文字只是做一个知识的总结。
    2、日志、消息记录;不需要事务,不需复杂join连接表;需要大容量存储;高吞吐量;数据不丢失;高可用;使用Mongo。

参考:

http://blog.csdn.net/sun49192...
https://www.zhihu.com/questio...
https://yq.aliyun.com/article...

相关文章:

【QT】Qtcreator的设计模式中将控件提升为自定义的控件

测试环境 在工程中添加自定义的控件 如:MyWidget 进入设计模式,右键需要提升的控件(该控件的父类必须和自定义控件的父类相同,否则不能提升),选择“提升为…”,在新建提升的类中填写类的名称…

文件时间信息在测试中的应用

1 简介文件时间信息在测试中也有妙用~ 通过记录模块运行前后的文件时间信息来识别运行前后发生变化的文件,从而识别模块运行前后的新增文件、删除的文件和内容发生变化的文件。 利用识别出来的发生变化的文件来减少复杂模块回归测试中采用新旧对比回归测…

SpringMVC之请求参数的获取方式

转载出处:https://www.toutiao.com/i6510822190219264516/ SpringMVC之请求参数的获取方式 常见的一个web服务,如何获取请求参数? 一般最常见的请求为GET和POST,get请求的参数在url上可以获取,post请求参数除了url上还…

生成假人脸、假新闻...AI虚拟世界正形成

整理 | 一一出品 | AI科技大本营(ID:rgznai100)AI 正在创造一个独特的虚拟(虚假)信息世界。一个人脸喂养生成网站火了。这个网站可以生成随机人脸图像,这些人脸没有姓名,在现实世界中并不存在,而…

【linux】ARM开发板上设置RTC时间,断电重启后,设置失效的原因分析

问题描述 linux中使用date设置时间后用hwclock -w同步到RTC,断电重启后,有时会失效 原因分析 保存时间戳 1、使用命令关机(halt)会调用rc0.d中的脚本; 2、使用命令重启(reboot)会调用rc6.d中…

【linux】NXP MFGTools工具配置文件详解

mfgtools\cfg.ini [profiles] chip Linux #对应mfgtools\Profiles\Linux\OS Firmware\中“Linux” #MfgTool2.exe中会使用路径:Profiles${chip}\OS Firmware [platform] board MY-IMX6 #没有用,可以忽略 [LIST] name Linux-3.14.52 #对应mfgtools\…

Python打造最强表白程序

作者 | 痴海转载自公众号痴海(ID:ch726612)情人节刚过,朋友圈又是刷屏的节奏。但热闹总是别人的,我们好像只有吃狗粮的份。时间总是飞快流逝,很多事情早已改变,但仿佛只有你的单身状态从未改变。单身久的我…

怎样加强你的意志力

每个人都有惰性,而且每天都在惰性进行斗争,而这个斗争在你死之前,是不会停止的。实际每个人都知道,每天应该坚持学习,早起早睡,可是到时候总是因为各种原因放弃。能坚持下来的人,离目标就更近一…

解除微信回调的Activity必须在包名.wxapi下的限制

很久以前写过一篇文章:Android打包之多版本、多环境、多渠道。里面主要提到了将测试环境和正式环境的包分成不同的包名,同时安装在手机上,以便我们调试。同时,通过manifest的占位符,动态替换icon和label,让…

FreeBSD 6.0架设管理与应用-第三章 UNIX 系统入门

在开始进阶的 FreeBSD 设定之前,我们先来了解一下 UNIX 系统的架构及基本知识。这些知识对于我们之后管理、使用 FreeBSD 十分重要。如果您是 UNIX 新手,请务必详读本章。本章将介绍下列主题:如何登入注销系统。 UNIX 的指令用法。 UNIX 中常…

京东金融App收集用户敏感信息?致歉来了

整理 | 琥珀出品 | AI科技大本营(ID:rgznai100)京东金融 App 收集用户信息大家看到的是安全隐患,而我们看到的是一个大企业的原罪。日前,就京东金融 App 疑似收集信息事件引起了网络上的轩然大波。就该起事件,京东金融…

安装Python的wx库

2019独角兽企业重金招聘Python工程师标准>>> 遇到问题1:pip不是内部或外部命令,也不是可运行的程序 解决办法:修改环境变量:变量值改为:C:\Python27\;C:\Python27\Scripts; 遇到问题2:wxPython.…

【linux驱动】嵌入式 Linux 对内存的直接读写(devmem)

devmem工具源码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #include <ctype.h> #include <termios.h> #include …

【视频】V4L2之ioctl

常见的ioctl命令 VIDIOC_QUERYCAP /* 获取设备支持的操作 */ VIDIOC_G_FMT /* 获取设置支持的视频格式 */ VIDIOC_S_FMT /* 设置捕获视频的格式 */ VIDIOC_REQBUFS /* 向驱动提出申请内存的请求 */ VIDIOC_QUERYBUF /* 向驱动查询申请到的内…

我们期待的TensorFlow 2.0还有哪些变化?

来源 | Google TensorFlow 团队为提高 TensorFlow 的工作效率&#xff0c;TensorFlow 2.0 进行了多项更改&#xff0c;包括删除了多余的 API&#xff0c;使API 更加一致统一&#xff0c;例如统一的 RNNs (循环神经网络&#xff09;&#xff0c;统一的优化器&#xff0c;并且Pyt…

多线程概念与编程

一、多线程的生命周期&#xff1a;新建(New)、就绪&#xff08;Runnable&#xff09;、运行&#xff08;Running&#xff09;、阻塞(Blocked)和死亡(Dead) 1、新建状态&#xff1a;程序初始化一个Thread时&#xff0c;线程处于新建状态 2、就绪状态&#xff1a;线程Thread调用s…

C技巧:结构体参数转成不定参数

下面这段程序是一个C语言的小技巧&#xff0c;其展示了如何把一个参数为结构体的函数转成一个可变参数的函数&#xff0c;其中用到了宏和内建宏“__VA_ARGS__”&#xff0c;下面这段程序可以在GCC下正常编译通过&#xff1a; #include <stdio.h> #define func(...) myfun…

Arbitrage--POJ 2240

1、题目类型&#xff1a;图论、最短路径、Floyd算法。 2、解题思路&#xff1a;Floyd算法的简单应用&#xff1b;STL中map的简单应用。 3、注意事项&#xff1a;避免map报警告&#xff0c;文件开始调用#pragma warning(disable:4786)。 4、实现方法: #pragmawarning(disable:47…

【视频】V4L2之应用流程

####打开设备文件 int fd = open(Devicename,mode); Devicename:/dev/video0、/dev/video1 …… Mode:O_RDWR [| O_NONBLOCK] 如果使用非阻塞模式调用视频设备,则当没有可用的视频数据时,不会阻塞,而立刻返回。 ####取得设备的capability struct v4l2_capability capabil…

Android NDK开发之旅29 云服务器Ubuntu下搭建NDK环境,并编译FFmpeg

###前言 因为在Linux环境下编译FFmpeg生成库和头文件下比较方便&#xff0c;所以接下来主要操作在Linux环境下进行。但是对于Android NDK 开发新手来说&#xff0c;自己电脑配置Ubuntu Linux环境过程比较繁琐。而采用云服务器极大的方便了此过程&#xff0c;服务器对客户端远程…

一个App卖了4亿美元,这家听声识曲公司为何得到Apple的青睐?

作者 | 琥珀 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 是否可以将 Shazam 称为有听歌识曲功能应用的鼻祖&#xff1f; 2018 年 9 月&#xff0c;苹果最终以 4 亿美金完成对 Shazam 公司的收购&#xff0c;让不少人为之振奋&#xff0c;在当时对外公布的一份声…

Product Orders(生产订单)状态相关函数BAPI

[相关表] JEST-对象的系统状态&#xff08;I****&#xff09;和用户状态(E****) JSTO-状态对象信息 TJ02T-系统状态文本 -用户状态文本 【锁对象】&#xff1a;生产订单锁对象 ESORDER 函数&#xff1a; ENQUEUE_ESORDER&#xff0c; DEQUEUE_ESORDER [函数1]&#xff1a;检…

5行代码就能入门爬虫?

作者 | 苏克1900来源 | 第2大脑&#xff08;ID&#xff1a;Mocun6&#xff09;责编 | swallow不少读者是刚刚入门Python或者想学习Python的&#xff0c;今天就来谈谈如何用快速入门爬虫。先说结论&#xff1a;入门爬虫很容易&#xff0c;几行代码就可以&#xff0c;可以说是学习…

【云周刊】第146期:史上最大规模人机协同的双11,12位技术大V揭秘背后黑科技...

摘要&#xff1a;史上最大规模人机协同的双11&#xff0c;12位技术大V揭秘背后黑科技&#xff0c;INTERSPEECH 2017系列 | 语音识别之语言模型技术&#xff0c;机器学习初学者必须知道的十大算法&#xff0c;云数据库SQL Server 2016和新技术应用...更多精彩内容&#xff0c;尽…

【驱动】GNSS驱动基础

GNSS:Global Navigation Satellite System(全球卫星导航系统) GPS:Global Positioning System(全球定位系统) GPS是美国的卫星导航系统。 还有&#xff0c;俄罗斯的GLONASS&#xff1b;欧盟的Galileo&#xff1b;中国的北斗。 这几大导航系统统称为GNSS GLONASS、Galileo、…

ibaits插入即获取主键(mssql,mysql,oracle)

oracle主键需预先生成&#xff0c;通过sequence&#xff1b;mysql和mssql是插入后生成。 mysql: <insert id"insertStu_mysql" parameterClass"stu"> insert into stu(name) values (#name#) <selectKey resultClass"int" keyProper…

【驱动】GNSS驱动:gpsOneXTRA 援助技术

什么是 “gpsOneXTRA 援助技术”&#xff1f; 高通 gpsOneXTRA 的援助技术在公司的改进中扩展了 gps 芯片组, 允许通过互联网连接下载辅助 gps。芯片组为更精确的位置发现提供了更高的灵敏度, 尤其是在通常难以找到 GPS 信号的位置。 gpsOneXTRA:帮助提高了独立的性能&#x…

2017年书单整理

android书籍: Android进阶之光 刘望舒 点评一下&#xff0c;这本书呢&#xff0c;涉猎很广&#xff0c;涉及的技术&#xff0c;开源库挺多的&#xff0c;适合广度面上的知识增长&#xff0c;对于深度上的提高价值不大&#xff0c;我觉得对我没啥太大价值额 Android安全技术揭秘…

华南理工大学院长涉嫌篡改8名研究生成绩,4人已停职

整理 | 一一出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;2 月 11 日&#xff0c;网友平凡的世界overlooker 在新浪微博上报料&#xff0c;称华南理工大学计算机科学与工程学院的院领导于 2018 年研究生复试结束后&#xff0c;篡改 8 位考生的考试成绩&#xff0c;…

我心中的最佳阵容

世界杯的激情还在心中涤荡&#xff0c;但新赛季的各大联赛却已悄然开打&#xff0c;这里给出我心中的几项最佳&#xff0c;期待他们本赛季的完美表现。 最佳球队&#xff1a;切尔西&#xff08;上赛季切尔西在安帅执掌球队的首个赛季便夺得英超冠军&#xff0c;欧冠虽惜败于曾经…