zoukankan      html  css  js  c++  java
  • Memcached、Redis、MongoDB

    Memcached:
    Memcache就是一个普通的程序,这个程序进程先申请一个内存,预先将可支配的内存空间进行分区,
    每个分区里再分成多个块最大1M,但同一个分区里,块的长度是固定的,当数据来的时候通过Socket
    Socket有一个监听的端口,往端口发送一个字符串过来,解析字符串如果是插入操作,就将数据进行计算
    查找适合自己长度的快,然后插入进去
    为什么分块?解决内存碎片的问题

    当客户端来了一个key/value数据后,它怎样分配数据,将数据放到哪个服务器机器上呢?
    1、先将key一个哈希算法
    2、根据哈希值对服务器的个数取余,根据取余的结果选中存储当前key-value值的服务器
    3、如果加一台机器,客户端取数据的时候根据key取余有可能出现问题,原先可能将数据存到第二台服务器上,新
    加机器后有可能去第三台机器上取数据,而第三台机器没有这个数据,怎么解决这个问题?
    这个问题直接解决不了,只能把影响降到最低,这里就有一个一致性哈新算法

    用Memcached缓存如果其中内存不够时,想扩充这个分布式集群的时候,怎么一个
    方式可以解决这个数据的问题?
    答:一致性哈希算法


    Redis:redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hashs(哈希类型)。redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

    MemCache怎么解决数据冲突(并发访问、同时修改文件):
    CAS协议:数据过来的时候带一个自己的版本,允许最后一个获取服务端数据的人修改
    1、不能作为持久化存储
    2、存储的数据有限制,最多1M,大于1M人为进行分割
    3、存储的数据只能是key-value
    4、集群数据没有复制和同步机制(一台机器挂了,其他机器的数据也就没了)
    5、内存回收不及时 LRU算法:未使用内存-》过期内存-》最近最少使用内存
    Memchae与Redis不同:
    1、集群不相同
    mm:通过客户端驱动实现集群化
    Redis:通过服务器端配置实现集群
    2、Redis可以进行持久化
    1/数据文件恢复数据 rdb文件
    2/通过日志恢复数据
    3、Redis提供高级的数据结构。队列、栈等都提供支持
    4、Redis是单线程的。处理数据比较小的情况下没有太大区别,处理大数据mm
    性能更高,mm是多线程

    缓存系统的更新机制设计问题。
    如下是一个可行的解决方案(假设我们的更新机制是每5分钟更新一次缓存):
    1)设计两个缓存池,记为A、B,而A和B的内容都是从后端服务器数据库中获取到的数据。正常情况下,客户端的请求都是从缓存池A中获取缓存内容,同时,设置一个全局的变量ref用于记录当前正在访问缓存A的客户端数量,来一个客户端请求将ref值加1,响应完一个客户端请求后ref减一。
    2)当缓存更新时间到时,如果ref不为0,则我们不能直接更新缓存,因为这时有客户端正在从缓存池A取数据。这里,我们可以借鉴Redis的rehash思想,更新时间到,我们将客户端的访问都引导到B缓存池,此时的缓存池A不再接受新的客户端数据请求,A的ref变量只减不增,当ref变量减少到0时,我们便可以更新A缓存池中的内容了。

    MongoDB是一种面向集合(collection)的,模式自由的文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据。
    mongoDB不支持事务, 可在服务器端执行任意的 javascript函数,支持 javascript表达式查询,内建自动分片机制(支持水平数据库集群)
    所谓“面向集合”(Collection-Oriented),意思是数据被分组存储在数据集中,被称为一个集合(Collection)。
    每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档


    MongoDB:
    1、读写性能非常高,适应大数据[本身的这种存储结构,面向集合存储]]
    列之间没关系、没约束,就一个列,大部分操作都在内存里面完成
    Redis:并不是写入一条数据就立即写到磁盘,超过某个阀值时才写入磁盘
    MongoDB:写入也都写入内存里去,写入请求就立即返回,不关心有没有写入磁盘,
    用db.Users.getLashError()查看有没有写入成功,读也很快:使用空间换时间技术,
    把磁盘数据映射到内存里去,而且占用内存的优先级比较低,官网说的

    2、学习成本低、入门容易,上手简单,配置方便,能够非常快速解决我们项目中的问题

    3、文档型的数据库,无模式:数据结构预先没有规定

    4、可以支持部分的复杂查询

    为什么需要NoSQL非关系型数据库?

    High performance - 对数据库高并发读写的需求
    Huge Storage - 对海量数据的高效率存储和访问的需求
    High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求

    为什么用NoSQL而不用传统的数据库?
    1、传统的数据库高并发访问容易造成死锁
    2、搭建集群很简单,多客户端可以共享缓存
    3、读写性能很好,1s可以读取1w次,写10w次
    4、可以实现服务器与多个客户端之间主从数据同步

  • 相关阅读:
    如何实现shell并发 一个入门级可控多线程shell脚本方案
    Android SDK 开发指南
    Android SDK上手指南:知识测试
    JavaScript apply
    chrome 调试
    jQuery file upload上传图片出错分析
    jQuery插件开发
    yarn
    What is 'typeof define === 'function' && define['amd']' used for?
    jQuery .closest()
  • 原文地址:https://www.cnblogs.com/xiaoweigogo/p/7799492.html
Copyright © 2011-2022 走看看