Apache Ignite.NET 2.8的新功能
瘦客户端和分区感知
从一开始,Ignite就支持客户端和服务端连接模式。不过即使客户端模式不存储数据也不执行计算,它仍然相对“笨重”,启动Ignite.NET客户端节点需要一个嵌入式的JVM环境,可能至少需要一秒钟,并且消耗几兆字节的内存。
在某些场景中,例如短期在线应用、低功耗客户端主机、命令行工具等,可能不希望这样的架构。因此Ignite从2.4版本开始,新增了轻量级的瘦客户端协议来处理这些场景,下面是简单的比较:
胖客户端 | 瘦客户端 | |
---|---|---|
启动时间 | 1300 ms | 15 ms |
内存占用 | 40 MB (.NET + Java) | 70 KB |
是否需要 Java | 是 | 否 |
Ignite.NET瘦客户端通过Ignition.StartClient()
启动,并提供一组和胖客户端类似的API。根接口是分开的(IIgnite
-> IIgniteClient
,ICache
-> ICacheClient
),但是方法的命名方式相同,并且大多数代码可以轻松地来回切换。
瘦客户端协议是开放、可扩展并且文档化的,这样也为其他语言(例如Python、JavaScript和PHP)的客户端铺平了道路。
分区感知
瘦客户端的初始实现使用接入指定服务端节点的单个连接来执行所有的操作。大家都知道Ignite在集群节点之间平均分配缓存数据,当瘦客户端连接到节点A,但请求的数据在节点B上时,则必须从A到B发出另一个网络请求,这样并不高效。
Ignite从2.8版本开始,引入了瘦客户端分区感知功能:瘦客户端可以接入所有服务端节点,确定给定键的主节点,并将请求直接路由到该节点,从而避免了额外的网络负载。这种路由非常快,它通过键哈希值的一些基本数学运算,就可以根据已知的分区分布确定目标节点。通过IgniteClientConfiguration.EnablePartitionAwareness = true
打开/关闭分区感知后,cache.Get
操作的性能测试结果如下:
| Method | Mean | Error | StdDev | |------------------ |---------:|---------:|---------:| | Get | 90.73 us | 2.114 us | 5.892 us | | GetPartitionAware | 31.56 us | 0.618 us | 1.234 us |
具体测试中,集群拓扑、网络速度和缓存数据量可能有所不同,测试结果可能会不一样,但改进幅度是很大的。
故障转移
瘦客户端多节点连接还意味着故障转移的能力:如果一个或多个服务端节点发生故障,则客户端会自动切换到其他连接。
跨平台支持:.NET Core、Linux、macOS
Ignite从2.4版本开始引入了.NET Core 2.x支持,最终放弃了和Windows相关的C++部分,并切换到JNI层的纯.NET实现,从而使Ignite.NET应用可以在Linux和macOS上运行。
Ignite在2.8版本中新增了官方的.NET Core 3.x支持,并且可以在该框架支持的任何操作系统上以任何模式运行:服务端、客户端、瘦客户端。
Ignite改进了NuGet软件包中处理jar文件的方式,使用MSBuild.targets文件替换了post_build
脚本,该文件更可靠,跨平台,并且可以通过dotnet build
以及dotnet publish
处理:.jar文件会被自动复制到构建和发布目录,从而生成一个独立的软件包。
注意最低系统要求仍然相同:.NET 4.0和Visual Studio2010,Ignite会保证主要版本(2.x)内的向后兼容性。但是在即将推出的Ignite 3.x中将切换到.NET Standard 2.0。
LINQ:Conditional和批量更新
SQL的UPDATE .. WHERE ..
或DELETE .. WHERE ..
在ORM和LINQ中通常无法实现。Ignite最终使用.Where()
来获取数据,然后一个一个更新,这个方案不是很理想,并且也不够优雅。
假设要冻结所有一年以上未使用我们网站的用户:
ICacheClient<int, Person> cache = client.GetCache<int, Person>("person"); var threshold = DateTime.UtcNow.AddYears(-1); IQueryable<ICacheEntry<int,Person>> inactiveUsers = cache.AsCacheQueryable() .Where(entry => entry.Value.LastActivityDate < threshold); foreach (var entry in inactiveUsers) { entry.Value.IsDeactivated = true; cache[entry.Key] = entry.Value; }
这个代码会将匹配的数据加载到本地节点,浪费内存并给网络造成了压力,这也违背了Ignite并置处理的原则:即将代码发到数据所在处,而不是将数据拉到代码所在处。
解决方法是使用SQL代替:
cache.Query(new SqlFieldsQuery( "UPDATE person SET IsDeactivated = true WHERE LastActivityDate < ?", threshold));
简单、简洁、高效:Ignite会将查询发送到所有节点,并对每个缓存数据在本地执行更新,从而避免了节点之间的任何数据移动。但是开发者不想要C#中的SQL,而是想要LINQ,因为它经过了编译器检查,并且由于IDE的高效而更易于读写。
Ignite在2.5中通过LINQ引入了DML更新(除了Ignite2.1中的删除操作):
cache.AsCacheQueryable() .Where(entry => entry.Value.LastActivityDate < threshold) .UpdateAll(d => d.Set(person => person.IsDeactivated, true));
它将效率和LINQ的优点结合起来,转换为与上面相同的SQL查询。
动态服务代理
IServices.GetDynamicServiceProxy()
是一个返回dynamic
实例的新API,这样就无需事先创建接口即可调用任意服务,例如:
interface ISomeService { int GetId(string data); } ... ISomeService proxy = ignite.GetServices().GetServiceProxy<ISomeService>("someService"); var id = proxy.GetId("foo");
可以替换为:
dynamic proxy = ignite.GetServices().GetDynamicServiceProxy("someService"); var id = proxy.GetId("foo");
这在POC、调用Java服务等许多场景中都很有用。
后续甚至还可以通过字符串名字调用服务的方法:
var methodName = "foo"; var proxy = (DynamicObject) ignite.GetServices().GetDynamicServiceProxy("someService"); proxy.TryInvokeMember(new SimpleBinder(methodName), new object[0], out var result);
总结
今后,瘦客户端协议及其各种语言的实现是Apache Ignite社区的主要方向之一,其中分区感知是一个重要的里程碑。下一步是自动服务端节点发现,这样就不必手动提供端点列表。在即将发布的版本中,还会将计算、服务、事务(已在Java瘦客户端中提供)和其他API添加到瘦客户端,瘦客户端的功能将变得更为强大。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
关于Java序列化的问题你真的会吗?
引言 在持久化数据对象的时候我们很少使用Java序列化,而是使用数据库等方式来实现。但是在我看来,Java 序列化是一个很重要的内容,序列化不仅可以保存对象到磁盘进行持久化,还可以通过网络传输。在平时的面试当中,序列化也是经常被谈及的一块内容。 谈到序列化时,大家可能知道将类实现Serializable接口就可以达到序列化的目的,但当看到关于序列化的面试题时我们却常常一脸懵逼。 1)可序列化接口和可外部接口的区别是什么? 2)序列化时,你希望某些成员不要序列化?该如何实现? 3)什么是 serialVersionUID ?如果不定义serialVersionUID,会发生什么? 是不是突然发现我们对这些问题其实都还存在很多疑惑?本文将总结一些Java序列化的常见问题,并且通过demo来进行测试和解答。 问题一:什么是 Java 序列化? 序列化是把对象改成可以存到磁盘或通过网络发送到其它运行中的 Java 虚拟机的二进制格式的过程,并可以通过反序列化恢复对象状态。Java 序列化API给开发人员提供了一个标准机制:通过实现 java.io.Serializable 或者 java.io...
- 下一篇
浅谈微服务架构
微服务来源 单体应用 微服务是相对于单体应用的,在介绍微服务之前,先简单介绍一下单体应用:通常是由三个重要部分组成:客户端界面(由HTML、JavaScript组成)、数据库(由许多的表组件构成一个通用的、相互关联的数据管理系统)、服务端应用。服务端应用处理客户端的HTTP请求、执行逻辑、检索并更新数据库中的数据、然后将处理后的数据返回给客户端。 一个单体应用被构建成一个系统时,业务中所有请求都要在单一的进程中处理完成,当访问量很高情况下服务器压力是很大的。当然可以水平扩展,利用负载均衡将实例布署到多台服务器中。 单体架构的缺点 [ ] 开发效率低 [ ] 代码维护难 [ ] 部署不灵活 [ ] 稳定性不高 [ ] 扩展性不高 云时代 在此之前单体应用也是很成功的,但是随着云时代的到来,单体应用就显得有些不妥了,特别是应用程序发布到云端的时候,一个功能的变更,需要统一的编译和发布。这样的架构模式很难使得一个模块的变更不影响到其他模块,而且在扩展方面也只能进行整体的扩展,不能根据正在运行的部分进行扩展。 微服务架构风格 云时代单体应用的尴尬导致了微服务架构风格的出现:以服务构建应用。 一...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- Hadoop3单机部署,实现最简伪集群
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度