以内存为中心的分布式数据库、缓存和处理平台,用于事务性、分析性和流式工作负载,提供内存速度在PB级规模。 Ignite 为应用和不同的数据源之间提供一个高性能、分布式内存中数据组织管理的框架。

架构

理解

ignite的集群为节点集群和嵌入式集群 Java启动的为嵌入式集群,可以不建立客户端或者使用精简客户端(thin Clint)来使用

三种节点架构:

Serve节点:存储数据,参与缓存,执行计算和流处理,部署服务网格。换句话说,server节点是功能最全的节点。默认情况下,启动一个Ignite节点都是以server节点的角色启动。

Client节点:不存储数据,但是可以通过Ignite APIs连接到server节点上,进行缓存的读写,参与计算任务,流处理,事务和服务网格。和server节点不同,如果需要把一个节点作为client节点,需要修改默认的配置。Client节点和server节点同时组成了Ignite集群,所以它们可以相互发现,相互连接。

Thin client:thin client不会加入Ignite的集群拓扑,它也不存储数据,也不参与执行计算和流处理。和Ignite原生的client节点不同,它并不感知集群的拓扑结构变化(增加/删除节点后,thin client并不知道),而且一次只能和Ignite集群中的一个节点连接通讯,当该节点失效后,它会从事先配置好节点列表中挑选一个新的节点,重新连接。

所有的节点默认都以服务端模式启动,客户端模式需要显式指定

启动配置:

启动节点:

ignite.sh path/to/configuration.xml

配置客户节点:

IgniteConfiguration cfg = new IgniteConfiguration();
Ignite ignite = Ignition.start(cfg);
Ignite实现了AutoCloseable接口,可以使用try-with-resource语句来自动关闭。

IgniteConfiguration cfg = new IgniteConfiguration();


// 开启客户端
cfg.setClientMode(true);

try (Ignite ignite = Ignition.start(cfg)) {
    //
}

集群部署:

(12条消息) CentOs7如何搭建Ignite单机及集群InsistChange的博客-CSDN博客ignite集群部署

//个人对配置java 的理解为如果改节点没有启动会启动该节点 ,如果启动会修改节点配置????

嵌入式节点,一般节点 。嵌入式节点可以靠Java配置类来让配置生效,可以通过get

新节点的加入或删除:

节点删除:

强制停止,会丢失数据。

正常的停止有:1.调用ignite.close(); 2.调用System.exit();

停止当前节点是会从集群中被剔除且从基线拓扑中提出:

基线拓扑:

Baseline Topology:(基线拓扑)ignite的集群自动分配功能 当有新的节点 添加或者减去 时 控制数据的在平衡(校正拓扑)

自动校正修改步骤:

当有新的节点加入或者删除后发生以下步骤:

  • Ignite会等待一个可配置的时间(默认为5分钟);

  • 如果在此期间拓扑中没有其他变更,则Ignite会将基线拓扑设置为当前节点集;

  • 如果在此期间节点集发生更改,则会更新超时时间。

需要基线拓扑开启对应的设置:

Ignite ignite = Ignition.start();
//开启基准拓扑
ignite.cluster().baselineAutoAdjustEnabled(true);
//延续时间的设置
ignite.cluster().baselineAutoAdjustTimeout(30000);

当基线拓扑自动调整功能启用后,基线拓扑会自动改变。这是纯内存集群的默认行为,但是对于开启持久化的集群,必须手动启用基线拓扑自动调整功能。该选项默认是禁用的,必须手动更改基线拓扑,可以使用控制脚本来更改基线拓扑。

启用基线拓扑自动调整:

如果集群中只要有一个数据区启用了持久化,则首次启动时该集群将处于非激活状态。在非激活状态下,所有操作将被禁止,必须先激活集群然后才能创建缓存和注入数据。集群激活会将当前服务端节点集合设置为基线拓扑。重启集群时,只要基线拓扑中注册的所有节点都加入,集群将自动激活,否则必须手动激活集群。

常用操作状态和

#查看集群状态
control.sh --state
#设置集群的激活
control.sh --set-state ACTIVE
#获取基线拓扑的列表输出中包含了当前的拓扑版本,基线中节点的一致性ID列表,以及加入集群但是还没有添加到基线的节点列表。
control.sh --baseline
#使用下面的命令可以往基线拓扑中添加节点。节点加入之后,会开启再平衡过程
control.sh --baseline add consistentId1,consistentId2,... [--yes]
#从基线拓扑中删除节点 (需要先停止当前的节点才能remove)
control.sh --baseline remove consistentId1,consistentId2,... [--yes]
#可以通过提供节点的一致性ID列表,或者通过指定基线拓扑版本来配置基线拓扑。
control.sh --baseline set consistentId1,consistentId2,... [--yes]
#要恢复指定版本的基线,可以使用下面的命令:????不太懂 
control.sh --baseline version topologyVersion [--yes]
#开启自动基线调整
control.sh --baseline auto_adjust enable timeout 30000
#关闭
control.sh --baseline auto_adjust disable

添加节点:

1、 首先先在一台节点中进行单机版安装(上方单机安装); 2、 执行ps –aux | grep ignite 获取ignite的pid,并将ignite进程杀死; 3、 将config目录下default-config.xml文件添加配置,如下:

<property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                        <property name="addresses">
                            <list>
                                <value>127.0.0.1:47500..47509</value>
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
        </property>

修改为:

<!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
        <property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                        <property name="addresses">
                        <!--此处放置全部节点IP 如下方-->
                            <list>
                                <value>192.168.11.13:47500..47509</value>
                                <value>192.168.11.14:47500..47509</value>
                                <value>192.168.11.15:47500..47509</value>
                            </list>
                        </property>
                    </bean> 
                </property>
            </bean>
        </property>
        <!--通信串行外设接口配置-->
        <property name="communicationSpi">
            <bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
                 <!--本节点IP-->
                <property name="localAddress" value="192.168.11.13" />
                <!--连接超时时长-->
                <property name="connectTimeout" value="60000" />
            </bean>
        </property>
    <!--网络超时时长 -->
        <property name="networkTimeout" value="60000"/>

也可以修改配置为组ip探测:相同组下也可互相检测

<bean class="org.apache.ignite.configuration.IgniteConfiguration">
​
    <property name="discoverySpi">
        <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
            <property name="ipFinder">
                <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                    <property name="multicastGroup" value="228.10.10.157"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>

使用使用baseline查看节点,再加入节点。最后激活集群即可。

理解:如果时加入已有的节点的话之要接入集群之后 如果没有开启自动的基准拓扑 需要手动 来查看节点是否添加成功

并加入基线拓扑结构 才算添加节点成功。

生命周期:官方文档中说 可以自定义类来设置缓存生命周期过程中之前做出处理

三,原理

发现机制:

通过配置同组发现:

tcp/ip:

同组发现配置相同的组播:

//发现类 通过这个类进行 相互发现
TcpDiscoverySpi spi = new TcpDiscoverySpi();
//可以具体的配置类  翻译为ip多个寻找者
TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
//设置相同的组ip
ipFinder.setMulticastGroup("228.10.10.157");
​
spi.setIpFinder(ipFinder);
//ignite配置类
IgniteConfiguration cfg = new IgniteConfiguration();
​
// 覆盖默认的spi.
cfg.setDiscoverySpi(spi);
​
// 启动节点
Ignite ignite = Ignition.start(cfg);

设置静态IP探测器

静态IP探测器实现了TcpDiscoveryVmIpFinder,可以指定一组IP地址和端口,IP探测器将检查这些IP地址和端口以进行节点发现。

只需提供至少一个远程节点的IP地址即可,但是通常建议提供2或3个规划范围内节点的地址。一旦建立了与提供的任何IP地址的连接,Ignite就会自动发现所有其他节点

TcpDiscoverySpi spi = new TcpDiscoverySpi();
​
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
​
// Set initial IP addresses.
// Note that you can optionally specify a port or a port range.
ipFinder.setAddresses(Arrays.asList("1.2.3.4", "1.2.3.5:47500..47509"));
​
spi.setIpFinder(ipFinder);
​
IgniteConfiguration cfg = new IgniteConfiguration();
​
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
​
// Start a node.
Ignite ignite = Ignition.start(cfg);

静态和组播IP探测器

可以同时使用基于组播和静态IP的发现,这时TcpDiscoveryMulticastIpFinder除了可以接收来自组播的IP地址以外,还可以处理预定义的静态IP地址,和上述描述的静态IP发现一样,下面是如何配置带有静态IP地址的组播IP探测器的示例:

TcpDiscoverySpi spi = new TcpDiscoverySpi();
​
TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
​
// Set Multicast group.
ipFinder.setMulticastGroup("228.10.10.157");
​
// Set initial IP addresses.
// Note that you can optionally specify a port or a port range.
ipFinder.setAddresses(Arrays.asList("1.2.3.4", "1.2.3.5:47500..47509"));
​
spi.setIpFinder(ipFinder);
​
IgniteConfiguration cfg = new IgniteConfiguration();
​
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
​
// Start a node.
Ignite ignite = Ignition.start(cfg);

理解:组ip 就好像时可以理解为 拥有同样的标识的属于一个集群 静态比较好理解 todo ???

同一主机内还可以开启集群隔离及 不同的集群要 星湖不影响 主要时色hi在不同的端口和组ip

数据模型:

在物理层,每个数据条目(缓存条目或表数据行)都以二进制对象的形式存储,然后整个数据集被划分为多个较小的集合,称为分区。分区均匀地分布在所有节点上。数据和分区之间以及分区和节点之间的映射方式都由关联函数控制。

在Ignite中,SQL表和键-值缓存的概念是相同(内部)数据结构的两个等效表示,可以使用键-值API或SQL语句或同时使用两者来访问数据。

理解:数据都是以二进制的形式存在ignite中,分布式存储的话 会将整个数据集分成一个数据分区(有的资料叫数据网格),不同的节点可以存储不同的数据分区 达到分布式的目的,而数据之间的关系并不是由元数据维护 而是提出概念叫关联函数,来控制数据分区的之间的联系

关联函数:

控制数据条目和分区以及分区和节点之间的映射。默认的关联函数实现了约会哈希算法。它在分区到节点的映射中允许一些差异(即某些节点可能比其他节点持有的分区数量略多)。但是,关联函数可确保当拓扑更改时,分区仅迁移到新加入的节点或从离开的节点迁移,其余节点之间没有数据交换。官方解释。。

cachemode:

PARTITIONED

在这种模式下,所有分区在所有服务端节点间平均分配。此模式是可扩展性最高的分布式缓存模式,可以在所有节点上的总内存(RAM和磁盘)中存储尽可能多的数据,实际上节点越多,可以存储的数据就越多。

REPLICATED模式不同,该模式下更新成本很高,因为集群中的每个节点都需要更新。而在PARTITIONED模式下,更新成本很低,因为每个键只需要更新一个主节点(以及可选的一个或多个备份节点)。但是读取成本会高,因为只有某些节点才缓存有该数据

REPLICATED

REPLICATED模式下,所有数据(每个分区)都将复制到集群中的每个节点。由于每个节点上都有完整的数据,此缓存模式提供了最大的数据可用性。但是每次数据更新都必须传播到所有其他节点,这可能会影响性能和可扩展性。

使用k-v api:

public class IgniteConfigTest {

    private static final String str2Int = "str2Int";
    private static final String int2Str = "int2Str";
    private static final String tagId2bitmap = "tagId2bitmap";

    //字符串用户id和int id关系数据
    public static IgniteCache< String, Integer > str2IntCache = null;

    //int id 和字符串用户id关系数据
    public static IgniteCache< Integer, String > int2StrCache = null;

    //存储标签id 和 其对应的用户id集合
    public static IgniteCache< Integer,  byte[]> tagId2bitmapCache = null;

    public static void main(String[] args) {
		//自动检测类
        TcpDiscoverySpi spi = new TcpDiscoverySpi();
        TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
        //服务端地址
        ipFinder.setAddresses(Arrays.asList("10.170.156.206","10.170.156.206:47500"));
        spi.setIpFinder(ipFinder);
        IgniteConfiguration igniteConfig = new IgniteConfiguration();
        //服务节点名称
        igniteConfig.setIgniteInstanceName("TestInstance");
        igniteConfig.setDiscoverySpi(spi);
        igniteConfig.setClientMode(true);
        //超时时间
        igniteConfig.setNetworkTimeout(30*1000);
		//获取ignite对象
        Ignite ignite = Ignition.start(igniteConfig);

		//缓存配置对象
        CacheConfiguration<Integer, String> cfg2 = new CacheConfiguration<>();
        cfg2.setName(int2Str);
        //支持原子性
        cfg2.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
        //索引类型
        cfg2.setIndexedTypes(Integer.class, String.class);
        //缓存模式
        cfg2.setCacheMode(CacheMode.PARTITIONED);
        //备份数
        cfg2.setBackups( 1);
        ignite.getOrCreateCache(cfg2);

        // 获取缓存对象
        int2StrCache = ignite.cache(int2Str);
        System.out.println("int2Str 结束 int2Str======");


        SqlFieldsQuery sqlFieldsQuery = new SqlFieldsQuery("select _KEY, _VAL  from STRING where _VAL = 'eee'");
//        SqlFieldsQuery sqlFieldsQuery = new SqlFieldsQuery("select _KEY, _VAL  from STRING where _VAL in('eee', 'ddd') ");
//        SqlFieldsQuery sqlFieldsQuery = new SqlFieldsQuery("select max(_KEY)  from STRING ");
        FieldsQueryCursor<List<?>> query = int2StrCache.query(sqlFieldsQuery);
        List<List<?>> all = query.getAll();
        for (List<?> row : all){
            System.out.println(" _KEY=" + row.get(0) + " ,,,_VAL=" + row.get(1));
        }

        System.exit(0);
    }


}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐