自从上次分享《Redis到底该如何利用?》已经有1年多了,这1年经历了不少。从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以总结下分享下拙见,期待能有更深入的研究。

缓存是什么?

我时常在群里或者在社区里看到有人对缓存有诸多疑问,搞不清缓存的用途,分不清.NET Redis各驱动、中间件的区别和选择。缓存其实并不是什么看起来很深奥或者很难驾驭的东西,它一般是用来保存一些常用的数据到内存,以加快数据读取,减少直接访问DB流量以降低DB压力。比较常用的场景比如:

  1. 静态的维表类数据,比如地址库,单位之类。
  2. 用户Session
  3. 一些实时性高,访问频率高的计算数据,比如用户访问次数,文章阅读量,用户黑名单之类。

传统的架构里,缓存纯粹是DB数据的一份Copy,就像上面所说是为了程序能更快的读取数据的。既然是Copy,其实就不必关心丢失,甚至微小的误差。一定是最先保证DB,然后才是考虑缓存。另外现在分布式大行其道,集群比比皆是,缓存的应有就分成了多级,从单机内存到集中式缓存最后穿透的DB

但是现在很多大型互联网架构里缓存是有不一样的应用的,比如新浪微博,他们使用Redis并不是简单的缓存,而是直接作为第一层的Storage,然后再异步写回DB。可以参考这篇

最近遇到一次很有意思的讨论,说到用户黑名单功能的设计。有朋友DB依赖性超强,上来就是用户表里加字段呀?读取太慢?加索引啊之类之类。我觉得这个挺有意思的,以前我也是想当然的这样想。为什么?一开始做项目都是设计数据库开始,建模就是ER图,上来就是DB 三范式。以至于其实现在我都很难改变这样的思维。导致学习OO,DDD之类建模思想始终绕不过DB First的思维。如果绕开DB,思考缓存去设计这样的功能,可行性和性能都能提高不少。

.NET下的缓存应用

针对单机应用,内存缓存(System.Runtime.Caching)就足够,集群环境应该上集中式缓存,比较常用的是memcached和Redis,这两者的区别倒是可以好好说到说到。

memcached更加的像内存缓存,功能单一,只能做普通的缓存操作(Put/Get/Remove...)

Redis功能更加丰富一些,也支持更多的数据结构,更多的计算命令,因此例如Session等缓存模块更加的适合memcached,而带实时计算性质的更加适合Redis。不过同时用上两种服务,也只有大公司能干了,一般人像我,还是比较喜欢Redis,毕竟功能丰富。

关于Redis的驱动,我也经常看到SeviceStack.Redis/StackExchange.Redis搞得大家不知道取舍。

两个我都用,因为ServiceStack本来是开源免费后来为了支撑发展吧,人家顺便就在V4之后开始加入限制,开始收钱了。不过V3依然免费,使用的时候需要注意所有的依赖都要用V3以下哦。V3版本很遗憾,很多功能并不能很好的支持,比如Pub/Sub.

StackExchange.Redis源自鼎鼎大名的StackOverFlow,他们有网站的收入,自然热衷开源免费。不过质量还是非常靠谱的,新功能支持的很好。

以上在GitHub上一搜便有。

另外一个开源项目CacheManager.NET最近也是很火,戳这里。很多人搞不懂它是什么样的定位,它实际上是一个中间件,本身并不直接提供与缓存(Redis\mem)的对接API,当前的版本它是使用了StackExchange.Redis来作为驱动的,博客园里已经有了很详细的介绍(这里)。它致力于屏蔽各种缓存服务的复杂度,提供简单一致的API,让开发者能够用一套代码,只要稍加配置就能使用MemroyCache/集中式缓存(redis/mem)。最强大的是它提供了多层缓存的方案(基于Redis Pub/Sub),只要简单的配置就达到了多层之间的缓存同步。(内部的原理是,通过Redis Pub/Sub,每当缓存变动就通知sub们自动remove掉响应的缓存)。我们公司最近的一次更新也切换到了CacheManager.NET,不得不说它真的很好用。

合理设计缓存

1. 合理设计Key

缓存最重要的特点的是其Key-Value形式,即使Redis的多样数据结构也是。Key-Value是保证其快速的根本原因,所以合理的Key,会让搜索更方便。

这也会让一份数据根据场景被设计成多分不同的Key-Value,例如:我之前的文章中提到的模糊匹配功能,就会把name设计进key,而如果是简单的根据userid取用户信息,则会把userid设计进key。从这里也可以看出缓存并不介意保存很多一样的数据。

2. 合理的使用缓存失效时间

上面提到缓存是可以丢失的,的确如果是内存缓存,它会随着应用的进程的终止而释放。除了这样的释放,缓存还可以被设置过期时间。为什么要如此设计呢?试想机器内存一定不会比硬盘大呀,空间有效,珍贵的资源自然是要保存尽可能常用的数据(热数据)。所以合理的设计失效时间会保持数据始终是最活跃的那一部分。当然失效时间也会引起,缓存雪崩等一系列问题,这里有一篇深入的文章值得去看看(戳这里

未完待续。。。下一篇会继续分享目前我所使用的缓存模块,《.NET的缓存模块设计》,涉及到ServiceStack.Redis的特性利用,CacheManager.NET的利用。

再谈缓存和Redis的更多相关文章

  1. 谈缓存和Redis

    自从上次分享<Redis到底该如何利用?>已经有1年多了,这1年经历了不少.从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以 ...

  2. 再谈Redis应用场景(转)

    原文:在谈Redis应用场景 一.MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样 ...

  3. 浅谈HTTP中Get与Post的区别/HTTP协议与HTML表单(再谈GET与POST的区别)

    HTTP协议与HTML表单(再谈GET与POST的区别) GET方式在request-line中传送数据:POST方式在request-line及request-body中均可以传送数据. http: ...

  4. 数据库缓存mybatis,redis

    简介 处理并发问题的重点不在于你的设计是怎样的,而在于你要评估你的并发,并在并发范围内处理.你预估你的并发是多少,然后测试r+m是否支持.缓存的目的是为了应对普通对象数据库的读写限制,依托与nosql ...

  5. 再谈HTTP2性能提升之背后原理—HTTP2历史解剖

    即使千辛万苦,还是把网站升级到http2了,遇坑如<phpcms v9站http升级到https加http2遇到到坑>. 因为理论相比于 HTTP 1.x ,在同时兼容 HTTP/1.1 ...

  6. 从网卡发送数据再谈TCP/IP协议—网络传输速度计算-网卡构造

    在<在深谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP>里面提到 单个TCP包每次打包1448字节的数据进行发送(以太网Ethernet最大的数据帧是1518字节,以 ...

  7. python之路--小数据池,再谈编码,is和 == 的区别

    一 . 小数据池 # 小数据池针对的是: int, str, bool 在py文件中几乎所有的字符串都会缓存. # id() 查看变量的内存地址 s = 'attila' print(id(s)) 二 ...

  8. spring(三、spring中的eheche缓存、redis使用)

    spring(三.spring中的eheche缓存.redis使用) 本文主要介绍为什么要构建ehcache+redis两级缓存?以及在实战中如何实现?思考如何配置缓存策略更合适?这样的方案可能遗留什 ...

  9. python的小数据池 is和== 以及再谈编码

    ---恢复内容开始--- 1. 小数据池, id() 小数据池针对的是: int, str, bool 在py文件中几乎所有的字符串都会缓存. id() 查看变量的内存地址 # a = 10 # b ...

随机推荐

  1. 《SQL必知必会》学习笔记(二)

    咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语句,但是实际应用中的业务逻辑往往会非常复杂,所 ...

  2. Make 命令教程

    http://www.ruanyifeng.com/blog/2015/02/make.html 作者: 阮一峰 日期: 2015年2月20日 代码变成可执行文件,叫做编译(compile):先编译这 ...

  3. 检查Linux服务器性能

    如果你的Linux服务器突然负载暴增,告警短信快发爆你的手机,如何在最短时间内找出Linux性能问题所在? 概述通过执行以下命令,可以在1分钟内对系统资源使用情况有个大致的了解. • uptime• ...

  4. iTunes Connect 显示可供销售,但是AppStore 就是不显示新版本(异于往常版本更新)

    这次版本更新,从上传到审核通过不足8小时.由于是手动发布,第二天早上上班发布了新版本.但是不同于往常,这次等了很久也不见AppStore 更新新版本.检查一下iTunes Connect ,显示可供销 ...

  5. Fedora20-64bit cross-compiling arm-linux-gcc

    0按照友善之臂的手册建立交叉编译环境时,添加用户变量,最好是去更改 profile 文件 因为 profile 是所有用户都可以使用的,类似于 windows 中的系统变量 而 .bashrc 只有该 ...

  6. Python 自动化入门 day1复习

    一.Python介绍 Python是1989年圣诞节期间龟叔创造的一种解释型语言. 最新的TIOBE排行榜 目前Python主要应用领域: 云计算: 云计算最火的语言, 典型应用OpenStack W ...

  7. 随笔分类 - Android之工具类

    Android之文件搜索工具类 /** * @detail 搜索sdcard文件 * @param 需要进行文件搜索的目录 * @param 过滤搜索文件类型 */ private void sear ...

  8. MySQL复制和集群

    一.复制配置 (A) 主从服务器相同版本的数据库 (B) 主服务器上复制使用的账户,具有相应的权限. (C) 修改主服务器的配置文件my.cnf,开启BINLOG,并设置server-id的值.重启后 ...

  9. Java并发1——线程创建、启动、生命周期与线程控制

    内容提要: 线程与进程 为什么要使用多线程/进程?线程与进程的区别?线程对比进程的优势?Java中有多进程吗? 线程的创建与启动 线程的创建有哪几种方式?它们之间有什么区别? 线程的生命周期与线程控制 ...

  10. CAD打印线条太粗、线条颜色设置

    不管你是使用打印机,还是将CAD转换为PDF文件,如果出现以下情况,线条太粗,根本看不清楚,怎么解决呢? 或者,不想通过图层复杂.繁琐的设置,想将各种颜色线条的CAD全部打印成黑白,或者指定某一种颜色 ...