To create high-performance systems, sometimes you need to cache data. Play has a cache library and will use Memcached when used in a distributed environment.

If you don’t configure Memcached, Play will use a standalone cache that stores data in the JVM heap. Caching data in the JVM application breaks the “share nothing” assumption made by Play: you can’t run your application on several servers, and expect the application to behave consistently. Each application instance will have a different copy of the data.

It is important to understand that the cache contract is clear: when you put data in a cache, you can’t expect that data to remain there forever. In fact you shouldn’t. A cache is fast, but values expire, and the cache generally exists only in memory (without persistent backup).

So the best way to use the cache is to repopulate it when it doesn’t have what you expect:

public static void allProducts() {
List<Product> products = Cache.get("products", List.class);
if(products == null) {
products = Product.findAll();
Cache.set("products", products, "30mn");
}
render(products);
}

The cache API

The cache API is provided by the play.cache.Cache class. This class contains the set of methods to set, replace, and get data from the cache. Refer to the Memcached documentation to understand the exact behavior of each method.

Some examples:

public static void showProduct(String id) {
Product product = Cache.get("product_" + id, Product.class);
if(product == null) {
product = Product.findById(id);
Cache.set("product_" + id, product, "30mn");
}
render(product);
} public static void addProduct(String name, int price) {
Product product = new Product(name, price);
product.save();
showProduct(id);
} public static void editProduct(String id, String name, int price) {
Product product = Product.findById(id);
product.name = name;
product.price = price;
Cache.set("product_" + id, product, "30mn");
showProduct(id);
} public static void deleteProduct(String id) {
Product product = Product.findById(id);
product.delete();
Cache.delete("product_" + id);
allProducts();
}

Some methods start with the safe prefix – e.g. safeDeletesafeSet. The standard methods are non-blocking. That means that when you issue the call:

Cache.delete("product_" + id);

The delete method will return immediately and will not wait until the cached object is actually deleted. So if an error occurs – e.g. an IO error – the object may still be present.

When you need to make sure that the object is deleted before continuing, you can use the safeDeletemethod:

Cache.safeDelete("product_" + id);

This method is blocking and returns a boolean value indicating whether the object has been deleted or not. So the full pattern that ensures an item is deleted from the cache is:

if(!Cache.safeDelete("product_" + id)) {
throw new Exception("Oops, the product has not been removed from the cache");
}
...

Note that those being blocking calls, safe methods will slow down your application. So use them only when needed.

Don’t use the Session as a cache!

If you come from a framework that uses an in-memory Session implementation, you may be frustrated to see that Play allows only a small set of String data to be saved in the HTTP Session. But this is much better because a session is not the place to cache your application data!

So if you have been accustomed to doing things similar to:

httpServletRequest.getSession().put("userProducts", products);
...
// and then in subsequent requests
products = (List<Product>)httpServletRequest.getSession().get("userProducts");

In Play you achieve the same effect a little differently. We think it’s a better approach:

Cache.set(session.getId(), products);
...
// and then in subsequent requests
List<Product> products = Cache.get(session.getId(), List.class)

Here we have used a unique UUID to keep unique information in the Cache for each user. Remember that, unlike a session object, the cache is not bound to any particular User!

Configure memcached

When you want to enable a real Memcached implementation, enable Memcached and define the daemon address in your application.conf:

memcached=enabled
memcached.host=127.0.0.1:11211

You can connect to a distributed cache by specifying multiple daemon addresses:

memcached=enabled
memcached.1.host=127.0.0.1:11211
memcached.2.host=127.0.0.1:11212

Continuing the discussion

Learn about Sending emails.

Use a cache的更多相关文章

  1. ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core

    背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...

  2. [Java 缓存] Java Cache之 DCache的简单应用.

    前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...

  3. Spring cache简单使用guava cache

    Spring cache简单使用 前言 spring有一套和各种缓存的集成方式.类似于sl4j,你可以选择log框架实现,也一样可以实现缓存实现,比如ehcache,guava cache. [TOC ...

  4. 笔记:Memory Notification: Library Cache Object loaded into SGA

    笔记:Memory Notification: Library Cache Object loaded into SGA在警告日志中发现一些这样的警告信息:Mon Nov 21 14:24:22 20 ...

  5. ABP源码分析十三:缓存Cache实现

    ABP中有两种cache的实现方式:MemroyCache 和 RedisCache. 如下图,两者都继承至ICache接口(准确说是CacheBase抽象类).ABP核心模块封装了MemroyCac ...

  6. [Java 缓存] Java Cache之 Guava Cache的简单应用.

    前言 今天第一次使用MarkDown的形式发博客. 准备记录一下自己对Guava Cache的认识及项目中的实际使用经验. 一: 什么是Guava Guava工程包含了若干被Google的 Java项 ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(40)-精准在线人数统计实现-【过滤器+Cache】

    系列目录 上次的探讨没有任何结果,我浏览了大量的文章和个别系统的参考!决定用Cache来做,这可能有点难以接受但是配合mvc过滤器来做效果非常好! 由于之前的过滤器我们用过了OnActionExecu ...

  8. HTML5离线缓存(Application Cache)

    HTML5离线缓存又名Application Cache,是从浏览器的缓存中分出来的一块缓存区,要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源. ...

  9. 第三篇 Entity Framework Plus 之 Query Cache

    离上一篇博客,快一周,工作太忙,只能利用休息日来写一些跟大家分享,Entity Framework Plus 组件系列文章,之前已经写过两篇 第一篇 Entity Framework Plus 之 A ...

  10. HTML5应用程序缓存Application Cache

    什么是Application Cache HTML5引入了应用程序缓存技术,意味着web应用可进行缓存,并在没有网络的情况下使用,通过创建cache manifest文件,可以轻松的创建离线应用. A ...

随机推荐

  1. jqGrid实现当前页列合计与总计

    当前页列合计    js代码如下:   ... footerrow: true, gridComplete: function () { var rowNum = parseInt($(this).g ...

  2. javaweb回顾第十篇JSTL

    前言:JSTL(JSP Standard Tag Library)JSP标准标签库.它的目的是为了简化JSP的开发,如何没有JSTL可能我们开发的时候就需要写大量的自定义标签,无疑会加大开发难度,有了 ...

  3. MySQL(一) 数据表数据库的基本操作

    序言 这类文章,记录我看<MySQL5.6从零开始学>这本书的过程,将自己觉得重要的东西记录一下,并有可能帮助到你们,在写的博文前几篇度会非常基础,只要动手敲,跟着我写的例子全部实现一遍, ...

  4. Wait Type:IO_COMPLETION

    在等待 CXPACKET 完成的时间内,我查看 sys.dm_exec_requests ,发现Session的 Logical Read/Write, Physical Read 都没有变化.Wai ...

  5. 手动为php安装memcached扩展模块

    最近公司需要新部署几台服务器,主要就是lnmp平台,这几台服务器需要部署公司的系统,由于本屌刚入职时间不长,加上又是新手,所以对公司的架构一头雾水,前前后后折腾了一个月时间,终于磕磕绊绊的将系统服务器 ...

  6. Orlion个人博客 | 全栈工程师之路-www.orlion.ga

    自己用wordpress+bootstrap搭建了一个博客,网址http://www.orlion.ga,用来记录博主学习和成长,主要关注JAVA.LANMP.前端与客户端(Android).算法与数 ...

  7. JavaScript的学习--生成二维码

    有一些耗cpu的计算,完全可以在客户端上计算,比如生成二维码. qrcode其实是通过计算,然后使用jquery实现图形渲染和画图.支持canvas和table两种方式生成我们所需的二维码. 具体用法 ...

  8. GIF录制神器GifCam

    前几天偶然看到一款神器:GifCam! GifCam是什么? 一款录制gif动画图片的小软件,小到不足一兆. 使用方法(简单到不可思议) 百度 GifCam 下载: 不用安装,直接打开gifcam: ...

  9. JAVA之IO文件读写

    IO概述:                                                          IO(Input output)流 作用:IO流用来处理设备之间的数据传输 ...

  10. WCF服务创建与使用(双工模式)

    昨天发布了<WCF服务创建与使用(请求应答模式)>,今天继续学习与强化在双工模式下WCF服务创建与使用,步骤与代码如下. 第一步,定义服务契约(Service Contract),注意Se ...