• Use a cache


    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.

  • 相关阅读:
    yarn的学习之1-架构
    HDFS的存储策略
    搭建简单的hadoop集群(译文)
    构建高可靠hadoop集群之5-服务级别授权
    构建高可靠hadoop集群之4-保全模式
    构建高可靠hadoop集群之4-权限指引
    构建高可靠hadoop集群之3- Quorum Journal Manager
    构建高可靠hadoop集群之0-hadoop用户向导
    构建高可靠hadoop集群之2-机栈
    构建高可靠hadoop集群之1-理解hdfs架构
  • 原文地址:https://www.cnblogs.com/zhiji6/p/4446826.html
Copyright © 2020-2023  润新知