2017编程提高第6.5节课——缓存
LanyuanXiaoyao's Blog ヽ(✿゚▽゚)ノ

2017编程提高第6.5节课——缓存


Web应用的特点

  • 核心数据存放在数据库中
    • 用户,订单,交易…
    • 数据库是和编程语言无关的,通过sql交互
    • Java,PHP,ruby,Python ,C#等语言写的程序需要访问数据库,执行业务逻辑, 展示结果给用户

  • 数据库的局限
    • 数据库连接是非常“昂贵”的资源 ->连接池
    • 连接池的连接数是有限的, 如果用户过多,势必要等待
    • 读写数据时需要加锁
  • 每次用户请求都访问数据库,在多用户,大并发时是不行的

解决问题的思路

  • “计算机行业的所有问题,都可以通过增加一个抽象层来解决”
  • 在应用程序和数据库之间增加一个层:缓存层
  • 缓存的数据放在内存中

内存的优势

使用缓存后的Web架构

  • 第一次访问, 从数据库读取数据, 并且放到缓存中
  • 后续访问, 直接从缓存中读取
  • 数据发生变化,既要更新数据库, 也要更新缓存

假如你是架构师

  1. 缓存里放什么格式的数据?
  2. 应用程序如何访问缓存?
  3. 缓存空间被应用程序用完了怎么办?
  4. 要不要分布式存储(数据的分片), 怎么实现?

缓存里放什么格式的数据?

  • 序列化的对象
    • 语言专有(Java ,序列化,反序列化)
    • 语言独立 (protobuf)
  • XML?  JSON?
  • 字符串?  (key,value)
  • 基本的数据结构?

应用程序如何访问缓存

  • 编程语言无关
    • Ruby , Perl , PHP, Python,Java,C/C++, C# …
  • 客户端/服务器模型
    • 服务器监听请求
    • 客户端发出请求,获得响应……
    • 基于Socket的通信

缓存空间被用完了怎么办?

  • 缓存服务器端在启动的时候,会设置缓存大小
  • LRU(Least Recently Used) 算法
    • 清除最近最少使用的缓存数据

实现分布式存储 (数据分片)

  • 假设一个缓存服务器的内存满足不了系统的要求, 能不能支持多台缓存服务器?
  • 如果是多台服务器, 用什么算法让数据相对“平均”的存储? 并且容易增删服务器?
  • 这个算法应该在什么地方?

客户端实现

代理

路由

分布式存储: 余数算法

对于用户要存储的(key,value), 计算key 的整数哈希值,然后对服务器的数目求余, 这样来确定存储服务器

  • 3台服务器 : 0, 1, 2
    • Key1 的hash 假设是 100    100%3 = 1  – 放到编号为1的服务器中 
    • Key2 的hash 假设是 99       99% 3 = 0  – 放到编号为0的服务器中
  • 现在增加了一台服务器 : 0, 1, 2, 3
    • Key1 的hash 是100 , 100%4 = 0  — 到0号服务器器找, 找不到了!
    • Key2 的hash 是99 , 99%4 = 3 — 到3号服务器找, 也找不到了!

缺点:不支持动态的增删服务器,增加/删除服务器时, 余数变化巨大,这样就导致找不到存储数据的服务器,缓存中找不到→从数据库取 : 相当于重组缓存

分布式一致性hash算法

增加一个节点

缺点

  • 服务器的映射地点的分布非常不均匀
    • 导致有的服务器上缓存的数据多,有的缓存的少
  • 虚拟节点
    • 让一个服务器化身为多个虚拟节点,分布到环上

虚拟节点

Hash 槽

增加一个新节点

主从模式

数据如何从master 同步到salve ?

牺牲一致性

  1. 客户向nodeA (master) 写入数据
  2. nodeA(master) 对客户响应:操作成功
  3. nodeA 向nodeA1(slave), nodeA2(slave)做同步操作

在第3开始之前,如果nodeA 不幸down掉,写入的数据就会丢失

牺牲性能

  1. 客户向nodeA 写入数据
  2. nodeA向nodeA1, nodeA2做同步操作
  3. 同步成功以后再告知客户端写入成功

评论