Gemfire

介绍

分布式缓存,在金融领域应用广泛。

特点

竞争对手

历史

核心概念

Region:数据存储的节点,在Java中类似Map,在数据库中类似Table,支持查询和事务。

官方分类如下:

总结如下:

REGION是GEMFIRE的核心,一方面,我们把数据缓存在REGION中,另一方面,也从REGION中拿数据。

CLIENT/SERVER 架构

client <-> locator <-> server

LOCATOR:提供了发现和负载均衡服务。 客户端配置LOCATOR的服务列表,LOCATOR维护SERVER的动态列表。

CLIENT端有REGION,SERVER端也有REGION,这些REGION通过LOCATOR关联起来。

Region Type (Spring)

以下是SPRING DATA GEMFIRE对于REGION TYPE的分类:

示例:

<!-- 1 -->
<gfe:partitioned-region id="examplePartitionRegion" copies="2" total-buckets="17">
  <gfe:partition-resolver>
    <bean class="example.PartitionResolver"/>
  </gfe:partition-resolver>
</gfe:partitioned-region>

<!-- 2 -->
<gfe:replicated-region id="exampleReplica"/>

Client Region Shortcut (Spring)

当REGION是CLIENT REGION时,还可以为它指定额外属性SHORTCUT。进一步定义它是如何与SERVER REGION进行交互。

示例:

<gfe:client-cache/>

<gfe:client-region id="Example" shortcut="LOCAL"/>

Other Region Config (Spring)

Example with Pivotal Gemfire Cmd

In this example, we start a server, locator. Open a client, connect to the locator, then do some operation.

Step 1: install Pivotal Gemfire

Step 2: start a locator

gfsh>start locator --name=locator1

Step 3: start a server

gfsh>start server --name=server1 --server-port=40411

Step 4: create a region

gfsh>create region --name=regionA --type=REPLICATE_PERSISTENT
gfsh>list regions
gfsh>list members
gfsh>describe region --name=regionA

Step 5: manipulate data

gfsh>put --region=regionA --key="1" --value="one"
gfsh>put --region=regionA --key="2" --value="two"
gfsh>query --query="select * from /regionA"

Step 6: start a new window, connect to the same locator and query

gfsh>connect --locator=localhost[10334]
gfsh>query --query="select * from /regionA"

Step 7: shout down

gfsh>shutdown --include-locators=true

Example with Spring

In this example, we have

  1. On startup, SERVER starts all components and standby. Its Cache Server is bind to the port of Locator.
  2. CLIENT creates a Client Region with CACHING_PROXY, which means updates will send to SERVER but it also has a local copy of the data. Then it does some modification.
  3. We can see changes in both SERVER and CLIENT.

Note: Compared to Pivotal Gemfire, Spring Data Gemfire has a Cache Object, to hold Region.

server/cache-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:gfe="http://www.springframework.org/schema/gemfire"
       xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- Cache Server-->
    <gfe:cache-server />

    <!-- Cache -->
    <gfe:cache properties-ref="gemfire-props"/>

    <!-- Region -->
    <gfe:replicated-region id="Customer">
        <gfe:cache-listener>
            <bean class="util.LoggingCacheListener"/>
        </gfe:cache-listener>
    </gfe:replicated-region>

    <!-- Others -->
    <util:properties id="gemfire-props">
        <prop key="log-level">config</prop>
    </util:properties>

</beans>

client/cache-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
       xmlns:gfe="http://www.springframework.org/schema/gemfire"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd
		http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">

    <!--The data source creates a ClientCache and connection Pool.
    In addition, it will query the cluster servers for all existing root Regions and
    create an (empty) client Region proxy for each one.-->

    <!-- Client Cache -->
    <gfe-data:datasource>
        <gfe-data:server host="localhost" port="40404" />
    </gfe-data:datasource>

    <!-- Client Region -->
    <gfe:client-region id="Customer" shortcut="CACHING_PROXY">
        <gfe:cache-listener>
            <bean class="util.LoggingCacheListener"/>
        </gfe:cache-listener>
    </gfe:client-region>

</beans>

Server

public class Server {
    @SuppressWarnings("unchecked")
    public static void main(String args[]) throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("server/cache-config.xml");
        Region<Long, Customer> region = context.getBean(Region.class);

        // bind to locator
        try {
            new ServerPortGenerator().bind(new ServerSocket(), 40404,1);
        } catch (IOException e) {
            System.out.println("Sorry port 40404 is in use. Do you have another cache server process already running?");
            System.exit(1);

        }

        // standby
        System.out.println("Press <Enter> to terminate the server");
        System.in.read();

        // output the region values
        Set<Map.Entry<Long, Customer>> set = region.entrySet();
        Iterator<Map.Entry<Long, Customer>> ite = set.iterator();
        while (ite.hasNext()) {
            Map.Entry<Long, Customer> entry = ite.next();
            System.out.println("Server - region value: " + entry.getValue().toString());
        }
    }
}

Client

public class Client {
    @SuppressWarnings("unchecked")
    public static void main(String args[]) throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("client/cache-config.xml");
        Region<Long, Customer> region = context.getBean(Region.class);

        // put some data into region
        Customer dave = new Customer(1,"Dave","Matthews");
        Customer alicia = new Customer(2,"Alicia","Keys");
        Customer bob = new Customer(3,"Bob","West");
        region.put(dave.getId(),dave);
        region.put(alicia.getId(),alicia);
        region.put(bob.getId(),bob);
        System.out.println("Client - data creation in Region complete.");

        // output the region values
        Set<Map.Entry<Long, Customer>> set = region.entrySet();
        Iterator<Map.Entry<Long, Customer>> ite = set.iterator();
        while (ite.hasNext()) {
            Map.Entry<Long, Customer> entry = ite.next();
            System.out.println("Client - region value: " + entry.getValue().toString());
        }
    }
}

链接

Fork me on GitHub