缓存

我也简单谈下《Web应用的缓存设计模式》

吃可爱长大的小学妹 提交于 2020-03-26 10:52:15
拜读了Robbin的文章《Web应用的缓存设计模式》http://robbinfan.com/blog/38/orm-cache-sumup ,我觉得大体思想还是值得学习和借鉴的,借这机会顺便简单谈谈我一般的做法,基于它文章Blog的例子和场景。 以读取博客文章列表和文章为例 一、数据库设计 首先,从数据库设计上,我赞同Contents拆分出去,在显示列表时,是没必要读取完整内容的。但如果缓存应用得当,这个可以属于可选项,并非必须。按照我的习惯,表设计会如下: Blogs表,用以存储博客内容 BlogId int 用以存储博客内容,表主键,聚集索引 Title nvarchar(256) 博客标题 Content nvarchar(MAX) 博客内容 FormattedContent nvarchar(MAX) 格式化后博客内容,空间换时间,没必要消耗CPU去格式化markdown。可选项,也可以运算后放缓存 AuthorId   int 和Accounts表关联 Author nvarchar(256) 作者,冗余字段,可以不必查询Accounts表 BlogDate datetime 博客发布时间 补充说明: 1. 适当冗余,例如FormattedContent和Author字段,减少跨表查询或CPU运算 2.

视频直播技术传输和推流端的优化技术

冷暖自知 提交于 2020-03-26 10:37:07
3 月,跳不动了?>>> 上节为大家介绍了如何在视频直播技术中使用编码优化,今天继续为大家介绍传输和推流播放端的直播优化技术。 传输协议优化 1. 在服务端节点和节点之间尽量使用 RTMP 而非基于 HTTP 的 HLS 协议进行传输,这样可以降低整体的传输延迟。这个主要针对终端用户使用 HLS 进行播放的情况。 2. 如果终端用户使用 RTMP 来播放,尽量在靠近推流端的收流节点进行转码,这样传输的视频流比原始视频流更小。 3. 如果有必要,可以使用定制的 UDP 协议来替换 TCP 协议,省去弱网环节下的丢包重传可以降低延迟。它的主要缺点在于,基于 UDP 协议进行定制的协议的视频流的传输和分发不够通用, CDN 厂商支持的是标准的传输协议。另一个缺点在于可能出现丢包导致的花屏或者模糊(缺少关键帧的解码参考),这就要求协议定制方在 UDP 基础之上做好丢包控制。 传输网络优化 1. 我们曾经介绍过实时流传输网络,它是一种新型的节点自组织的网状传输网络,既适合国内多运营商网络条件下的传输优化,也适合众多海外直播的需求。 2. 在服务端节点中缓存当前 GOP ,配合播放器端优化视频首开时间。 3. 服务端实时记录每个视频流流向每个环节时的秒级帧率和码率,实时监控码率和帧率的波动。 4. 客户端(推流和播放)通过查询服务端准实时获取当前最优节点( 5 秒一次)

当程序执行一条查询语句时,MySQL内部到底发生了什么? (说一下 MySQL 执行一条查询语句的内部执行过程?

非 Y 不嫁゛ 提交于 2020-03-26 09:42:09
先来个最基本的总结阐述,希望各位小伙伴认真的读一下,哈哈: 1)客户端(运行程序)先通过 连接器 连接到MySql服务器。 2)连接器通过数据库权限身份验证后,会先查询数据库缓存是否存在(之前执行过相同条件的SQL查询),如果有会直接返回缓存中的数据。如果没有则会进入分析器。 3)进入 分析器 后会对查询语句进行词法语法的分析,判断该查询语句SQL是否存在语法错误,如果存在查询语法词法错误,会直接返回给客户端错误,如果正确则会进入优化器。 4) 优化器 会对查询语句进行优化处理:例如:如果一条语句用到了多个索引会判断哪个索引性能更好。 5)最终会进入 执行器 ,开始执行查询语句直到查询出满足条件的所有数据,然后进行返回。 下面我们详细的来说一 下: 假如说我们有一张 User 表 ,表里只有一个字段 ID ,当我们执行下边这条SQL语句时: mysql> select * fron T where ID = 10; 在我们眼中能看到的只是输入一条 SQL语句,返回一条查询结果,却不曾知道这条SQL在MySQL的内部经历了什么,下面我们来一步一步的分析一下;如下是MySQL的基本架构图,从图中可以清楚的看到SQL在MySQL中各个功能模块执行的过程: 大体来说,MySQL可以分为 Server层 和 存储引擎 两部分。 Server层:包括连接器、分析器、查询缓存、优化器、执行器等。

Redis常用问题

旧巷老猫 提交于 2020-03-26 07:49:08
总结经常遇到的问题:   1、redis如何保证数据不丢失     a、主从实时同步(除非主服务器挂了),数据实时同步     b、写log文件(短暂丢失)   2、雪崩+穿透(用乐观锁)     http://www.cnblogs.com/zhangweizhong/p/6258797.html 高并发(要用到缓存) 缓存雪崩   缓存雪崩是由于原有缓存失效(过期),新缓存未到期间。所有请求都去查询数据库,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。   1. 碰到这种情况,一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。( 只有一个请求去同步数据,其他的请求去排队不读数据库 ) public object GetProductListNew() { const int cacheTime = 30; const string cacheKey = "product_list"; const string lockKey = cacheKey; var cacheValue = CacheHelper.Get(cacheKey); if (cacheValue != null) { return cacheValue; } else { lock (lockKey) { cacheValue =

缓存2.1——缓存与数据库双写一致性

偶尔善良 提交于 2020-03-25 20:25:55
  你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?   一般来说,如果允许缓存可以稍微的跟数据库偶尔有不一致的情况,也就是说如果你的系统 不是严格要求 “缓存+数据库” 必须保持一致性的话,最好不要做这个方案,即: 读请求和写请求串行化 ,串到一个 内存队列 里去。   串行化可以保证一定不会出现不一致的情况,但是它也会导致系统的吞吐量大幅度降低,用比正常情况下多几倍的机器去支撑线上的一个请求。 一、Cache Aside Pattern 最经典的缓存+数据库读写的模式,就是 Cache Aside Pattern。 读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。 更新的时候 , 先删除缓存,然后更新数据库 。 为什么是删除缓存,而不是更新缓存?   原因很简单,很多时候,在复杂点的缓存场景,缓存不单单是数据库中直接取出来的值。比如可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据并进行运算,才能计算出缓存最新的值的。   另外更新缓存的代价有时候是很高的。是不是说,每次修改数据库的时候,都一定要将其对应的缓存更新一份?也许有的场景是这样,但是对于 比较复杂的缓存数据计算的场景 ,就不是这样了。如果你频繁修改一个缓存涉及的多个表,缓存也频繁更新

HTTP 3 代理、网关、隧道

本秂侑毒 提交于 2020-03-25 17:28:56
5. 与HTTP协作的Web服务器 一台Web服务器可搭建多个·独立域名的Web网站,也可作为通信路径上的中转服务器提升传输效率。 用单台虚拟主机实现多个域名: HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点。比如,提供Web托管服务(Web Hosting Service)的供应商,可以用一台服务器为多位客户服务,也可以以每位客户持有的域名运行各自不同的网站。这是因为虚拟主机(virtual host)的功能。 即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假想已具有多台服务器。 客户端使用HTTP协议访问服务器时,会经常采用类似www.hackr.jp这样的主机名和域名。 在互联网上,域名通过DNS服务映射到IP地址(域名解析)之后访问目标网站,当请求发送到服务器时,已经是以IP地址形式访问了。 所以,如果一台服务器内托管了多个域名时,当收到请求时就需要搞清楚究竟要访问哪个域名。 在相同的IP地址下,由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。 通信数据转发程序:代理、网关、隧道: 代理: 代理是一种有转发功能的应用程序,作用于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。 网关:

缓存设计使用过程中需要注意的坑

断了今生、忘了曾经 提交于 2020-03-25 17:17:24
3 月,跳不动了?>>> 案例1,缓存和DB的数据不同步(不一致) 后台系统CRM更新产品数据到DB,产品系统收到异步消息通知后,更新最新数据到缓存。这是一个最常见的缓存应用场景,我相信很多团队都是这样用的。在这个Case里容易出现的问题在于,如果产品系统收到消息后服务挂掉了,缓存没有正常更新,就出现缓存与DB的数据不同步,前端系统一直不能读到最新数据,导致业务异常。 解决方案: 1. mq消费端创建个本地消息表,对于消费失败的消息进行重试 2. 系统要有缓存更新的报警机制,方便更新失败或者重试超时后,可以人工介入进行补偿。 案例2, 同时被两次请求update时,db数据被错误覆盖 CRM系统更新了某个用户的Profile, 保存更新数据库后,通过MQ通知用户系统更新缓存,由于是异步更新延迟,在缓存更新前,用户系统收到前端的请求,读取了当前缓存里的用户数据,做了修改,并更新到DB中。出现的结果就是数据库里的CRM的更新被错误覆盖。 解决方案:缓存里的数据有一个标志位可以作为更新数据库数据的依据(Update_time or Version), 如果缓存里数据时间与数据库时间不能匹配,意味着另外一个服务更新了该数据,那么就先从DB里读取最新数据版本,然后在新版本上提交数据。 案例3, 并发查询缓存中同一数据,如果缓存没命中,导致DB瞬时被打爆 做促销活动的时候

JAVA反射原理

馋奶兔 提交于 2020-03-25 12:18:02
什么是反射? 反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等。除了检阅类信息外,还可以动态创建类的实例,执行类实例的方法,获取类实例的域值。反射使java这种静态语言有了动态的特性。 类的加载 java反射机制是围绕Class类展开的,在深入java反射原理之前,需要对类加载机制有一个大致的了解。jvm使用ClassLoader将字节码文件(class文件)加载到方法区内存中: Class clazz = ClassLoader.getSystemClassLoader().loadClass("com.mypackage.MyClass"); 可见ClassLoader根据类的完全限定名加载类并返回了一个Class对象,而java反射的所有起源都是从这个class类开始的。 ReflectionData 为了提高反射的性能,缓存显然是必须的。class类内部有一个useCaches静态变量来标记是否使用缓存,这个值可以通过外部配置项sun.reflect.noCaches进行开关。class类内部提供了一个ReflectionData内部类用来存放反射数据的缓存,并声明了一个reflectionData域,由于稍后进行按需延迟加载并缓存

浏览器缓存

这一生的挚爱 提交于 2020-03-25 11:19:46
3 月,跳不动了?>>> 缓存的分类有很多种,CDN缓存、数据库缓存、代理服务器缓存和浏览器缓存。造成强制缓存的字段有两个Expires和Cache-Control。 Expires Expires: Thu, 10 Nov 2017 08:45:11 GMT 是一个绝对时间,在响应消息头中,设置这个字段之后,就可以告诉浏览器,在未过期之前不需要再次请求。 Cache-Control 该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求,相对时间, max-age:即最大有效时间,在上面的例子中我们可以看到 no-cache:表示没有缓存,即告诉浏览器该资源并没有设置缓存 s-maxage:同max-age,但是仅用于共享缓存,如CDN缓存 public:多用户共享缓存,默认设置 private:不能够多用户共享,HTTP认证之后,字段会自动转换成private。 ` Cache-Control: max-age=2592000` 对比缓存 先从缓存中获取对应的数据标识,然后向服务器发送请求,确认数据是否更新,如果更新,则返回新数据和新缓存;反之,则返回304状态码,告知客户端缓存未更新,可继续使用。 缺点: 1. 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。 2.如果文件是通过服务器动态生成的

Mybatis(四) Mybatis缓存

瘦欲@ 提交于 2020-03-24 20:39:47
4.1 Mybatis缓存概念   缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存,我们可以避免频繁的与数据进行交互,进而提高响应速度。 Mybatis 也提供了对缓存的支持,分为一级缓存和二级缓存,通过下图来理解: 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession2直接的缓存区域(HashMap)是互相不影响。 二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper查询的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨SqlSession的。 4.2 一级缓存 4.2.1 一级缓存案例   mybatis一级缓存是默认开启的 @Test public void firstLevelCache() throws IOException { InputStream resourceAsSteam = Resources.getResourceAsStream("sqlMapperConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);