前一篇文章,咱们介绍了如何安装部署Ignite集群,而且尝试了用REST和SQL客户端链接集群进行了缓存和数据库的操做。如今咱们就来写点代码,用Ignite的Java thin client来链接集群。 在开始介绍具体代码以前,让咱们先简单的了解一下Ignite的thin client,以及背后的binary client protocol(*本来打算把thin client翻译为精简客户端,bianry client protocol翻译为二进制客户端协议,但总读的不顺口,就索性就不翻译了吧-_-|||*)。html
为了缓存数据的高性能读写,Ignite是节点内部须要维护一套高效的数据结构来记录一些元数据,因此若是在本身的应用程序中启动一个Ignite的server/client节点是要占用一些应用程序的CPU/内存资源的。另外,Ignite是一个分布式系统,单个节点须要和集群里的其余节点通信,又要消耗一些的网络资源。 所以不一样于server/client节点,thin client是一个Ignite轻量化的客户端。为何说它是轻量化的呢,由于thin client并不会加入到Ignite集群的拓扑中(即thin client的链接,断开不会致使Ignite集群拓扑发生变化,也不会触发相应的事件通知),不会存储任何集群的数据或是被作为计算节点接收计算任务。Thin client就是一个纯粹的客户端,它纯粹到经过最原始的socket链接到Ignite集群中的某一个节点进行全部的操做。java
在Ignite集群成功启动后,咱们会在日志看到“Topology snapshot [ver=1, servers=1, clients=0, CPUs=2, offheap=1.6GB, heap=1.0GB]”信息。这条日志里的clients和thin client不是一回事。按照以前介绍,thin client是不会加入Ignite集群的拓扑中去,理应不会出如今和拓扑相关的日志中,因此这里不要把thin client和集群中的client节点搞混了。git
这个连接详细的介绍了Binary Client Protocol的数据格式(好比采用的是litter-endian,Ignite的二进制对象描述用户数据),消息格式(定义了消息头格式,响应消息的格式,以及链接时如何进行握手保证版本兼容等)和各类缓存操做所需的操做编码和格式。 因此只要你按照Binary Client Protocol的要求,你能够用任何一种语言实现一个thin client。目前Ignite发布了两种语言的thin client的实现,一个是基于Java实现,一个是基于.Net实现。数据库
固然thin client虽然轻量化,也有它的问题。 Thin client写数据时只能先把数据发给其链接的节点,再由该节点将数据发送给集群内的其余节点作存储(同理,读数据也须要经过该节点才能传给thin client),这样thin client和这个节点间的网络颇有可能就成为瓶颈。而server/client节点间能够互联,利用数据分区,能够充分使用节点间的带宽。另外,当前链接节点出故障后,thin client只能随机选择一个启动时已知的节点进行重试,因为其不感知集群拓扑,即使有新节点加入,thin client也没法知道其存在,更不可能和其进行通信了。 因此仍是要根据本身应用的场景,看看究竟是server/client节点仍是thin client更合适。apache
上一篇文章中,咱们用Dbeaver链接Ignite后,用SQL语句进行建表,插入数据和查询数据。 在这个例子里,咱们就来看看如何经过Ignite的thin client支持的JCache APIs进行相同的操做。api
首先咱们先用用maven命令建立一个新的project,而后在pom.xml文件中添加如下ignite-core的依赖:缓存
<dependencies> <dependency> <groupId>org.apache.ignite</groupId> <artifactId>ignite-core</artifactId> <version>${ignite.version}</version> </dependency> </dependencies>
在看具体代码以前,让咱们先来大概了解一下这个例子中咱们要进行哪些操做以及步骤:网络
下面是主程序的代码:数据结构
import org.apache.ignite.Ignition; import org.apache.ignite.client.ClientCache; import org.apache.ignite.client.ClientException; import org.apache.ignite.client.IgniteClient; import org.apache.ignite.configuration.ClientConfiguration; public class IgniteThinClientExample { private static ClientCache<Integer, Province> provinceCache; private static ClientCache<String, City> cityCache; public static void main(String[] args) { System.out.println(); System.out.println("Ignite thin client example started."); //链接到Ignite集群,默认端口号为10800 ClientConfiguration cfg = new ClientConfiguration().setAddresses("192.168.0.110:10800"); //用java的try-with-resource statement启动client try (IgniteClient igniteClient = Ignition.startClient(cfg)){ System.out.println(); System.out.println("Begin create cache and insert data."); //建立两个缓存,具体步骤见该函数 creatCacheAndInsertData(igniteClient); System.out.println(); System.out.println("Begin query cache."); //根据输入开始查询 for(String city : args) { //先用城市名字,查询city缓存 City c = cityCache.get(city); Province p = null; if (c != null) { //在用城市数据中的province id查询province缓存 p = provinceCache.get(c.getProvinceId()); } //输出查询结果 if (c != null && p != null) { System.out.println("Find " + c.getName() + " in province " + p.getName()); } else { System.out.println("Cannot find " + city + " in any province."); } } } catch (ClientException e) { System.err.println(e.getMessage()); } catch (Exception e) { System.err.format("Unexpected failure: %s\n", e); } } private static void creatCacheAndInsertData(IgniteClient igniteClient) { //建立province缓存,用来存放省份信息,该缓存以省的id为key final String PROVINCE_CACHE_NAME = "province"; provinceCache = igniteClient.getOrCreateCache(PROVINCE_CACHE_NAME); //往province缓存中写入一些数据 int provinceId = 1; final Province on = new Province(provinceId++, "Ontario"); final Province ab = new Province(provinceId++, "Alberta"); final Province qc = new Province(provinceId++, "Quebec"); provinceCache.put(on.getId(), on); provinceCache.put(ab.getId(), ab); provinceCache.put(qc.getId(), qc); System.out.println("Successfully insert all provinces data."); //建立city缓存,用来存放城市信息,该缓存以城市的名字为key final String CITY_CACHE_NAME = "city"; cityCache = igniteClient.getOrCreateCache(CITY_CACHE_NAME); //往city缓存写入一些数据 int cityId = 1; final City toronto = new City(cityId++, "Toronto", on.getId()); final City edmonton = new City(cityId++, "Edmonton", ab.getId()); final City calgary = new City(cityId++, "Calgary", ab.getId()); final City montreal = new City(cityId++, "Montreal", qc.getId()); cityCache.put(toronto.getName(), toronto); cityCache.put(edmonton.getName(), edmonton); cityCache.put(calgary.getName(), calgary); cityCache.put(montreal.getName(), montreal); System.out.println("Successfully insert all city data."); } } public class City { private int id; private String name; private int provinceId; ... } public class Province { private int id; private String name; ... }
成功的编译project后,咱们能够启动这个client看看程序的输出结果:socket
$java -cp $IGNITE_HOME/libs/*:./ignite-thin-client-example-1.0-SNAPSHOT.jar IgniteThinClientExample Toronto Markham Edmonton Calgary Ignite thin client example started. Begin create cache and insert data. Successfully insert all provinces data. Successfully insert all city data. Begin query cache. Find Toronto in province Ontario Cannot find Markham in any province. Find Edmonton in province Alberta Find Calgary in province Alberta
由于咱们的city缓存中,并无Markham的信息,因此查询Markham的时候咱们也找不到对应的省份信息。可是查询Toronto,Edmonton和Calgary的时候,程序是能正确的返回其省份信息的。
在上面的例子中,有几个须要注意的地方:
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> <!-- Thin client connection configuration. --> <property name="clientConnectorConfiguration"> <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration"> <property name="host" value="192.168.0.100"/> <property name="port" value="新的端口号"/> <property name="portRange" value="30"/> </bean> </property> </bean>
咱们的插入和查询数据的时候,只用到了最简单缓存API--put和get。其实Ignite缓存的查询API比其余缓存更丰富,支持scan/SQL/text方式进行查询,这个咱们会在后面的文章慢慢介绍。
咱们用城市的名字查询完city缓存后,再拿着province id去查询province缓存。这两步查询实际上是能够合并成一个SQL的join查询,在后面介绍SQL查询时,咱们再来看看把两个缓存当作两张表作join操做。
这篇文章咱们介绍了Ignite的thin client,并用Ignite的Java think client实现了一个简单的例子,解释如何用thin client链接上Ignite集群,建立缓存,写入数据以及查询。 完整的代码和maven工程文件戳这里。
下一篇文章,咱们看看如何在本身的Java代码里启动Ignite集群及其相关配置。