简体   繁体   English

通过从Spring Boot应用程序加载数据映射来初始化GemFire缓存

[英]Initialize a GemFire cache by loading a Map of data from Spring Boot application

I am trying to develop a cache application which will load itself on server start and client application will be able to read the cache data through REST service calls. 我正在尝试开发一个缓存应用程序,该应用程序将在服务器启动时加载自身,并且客户端应用程序将能够通过REST服务调用读取缓存数据。

Hence, I have to initialize the GemFire cache at the deployment of the application. 因此,我必须在应用程序部署时初始化GemFire缓存。 This would load the data (derived the data from the RDBMS) which is in the form of Map into the Cache. 这会将Map形式的数据(从RDBMS派生而来)加载到Cache中。

I have seen a CacheLoader loading one entry at a time into a GemFire Region, but can Region.putAll(map) load all data at a time or are there some other methods? 我已经看到CacheLoader一次将一个条目加载到GemFire区域中,但是Region.putAll(map)可以Region.putAll(map)加载所有数据吗,或者还有其他方法吗?

Please help. 请帮忙。

I believe that the <initializer> element would be a perfect match for your use case here. 我相信<initializer>元素将非常适合您的用例。 It's used to Launch an Application after Initializing the Cache , and it can certainly be used to populate the regions upon cache initialization. 它用于在初始化Cache后启动应用程序 ,并且可以肯定地用于在初始化缓存时填充区域。

There are other options as well, like writing a custom Function and execute it as soon as your startup script returns, but I think that the <initializer> element would be the appropriate here. 还有其他选项,例如编写自定义函数并在启动脚本返回后立即执行它,但是我认为<initializer>元素在这里比较合适。

Hope this helps. 希望这可以帮助。 Cheers. 干杯。

I would be very careful about putting all the data from your underlying data source, eg from an RDBMS, in memory, in a java.util.Map , since it would be very easy to run out of memory (hence an OutOfMemoryError ) pretty quickly depending on the size of the result set. 对于将来自底层数据源(例如,来自RDBMS的数据)的所有数据放入内存中的java.util.Map ,我将非常小心,因为非常容易很快用完内存(因此OutOfMemoryError )取决于结果集的大小。

None-the-less, if you want an example of this see here ; 但是,如果您想要一个示例,请参见此处 configuration is here . 配置在这里

Essentially, I am using a Spring BeanPostProcessor , the RegionPutAllBeanPostProcessor , to put a Map of data into a "target" Region. 本质上,我使用的是Spring BeanPostProcessor (即RegionPutAllBeanPostProcessor) ,将数据Map放入“目标”区域。

For example, I have a Region (ie "RegionOne") and I can use the RegionPutAllBeanPostProcessor to target this Region and put data into the Region from the Map . 例如,我有一个Region (即“ RegionOne”),并且可以使用RegionPutAllBeanPostProcessor 定位此Region 并将数据 从Map放入Region中。

Obviously, you have many different options when it comes to triggering this Region load/"warming": a GemFire Initializer, a Spring BeanPostProcessor (docs here ) or even a Spring ApplicationListener listening for ApplicationContextEvents , such as an on ContextRefreshedEvent (docs here ). 很显然,你有很多不同的选择,当谈到触发该区域负载/“升温”:一个的GemFire初始化器,一个Spring BeanPostProcessor (文档在这里 ),或者甚至是春天ApplicationListener监听ApplicationContextEvents ,如在ContextRefreshedEvent (文件在这里 )。

However, while the Map in this test is hard-coded in XML, you could envision populating this Map from any data source, including a java.sql.ResultSet derived from a SQL query executed against the RDBMS. 但是,尽管此测试中的Map是用XML硬编码的,但是您可以设想从任何数据源(包括从对RDBMS执行的SQL查询派生的java.sql.ResultSet填充此Map

So, perhaps a better approach/solution, that would not eat up as much memory, would be to use a BBP "injected" with Spring's JdbcTemplate or a JPA EntityManager , or even better yet, use Spring Data JPA , and load the data from your framework of choice to put data directly into the Region. 因此,也许不会消耗太多内存的更好的方法/解决方案是使用通过Spring的JdbcTemplate或JPA EntityManager “注入”的BBP,或者甚至更好的是,使用Spring Data JPA并从中加载数据您选择的框架直接将数据放入区域。 After all, if the Region.putAll(:Map) is essentially just iterating the Map.Entries of the incoming Map and calling Region.put(key, value) individually for each Map.Entry ( this , this and this ) , then clearly it is not buying you that much and certainly does not justify putting all the data in-memory before putting it into the Region. 毕竟,如果Region.putAll(:Map)本质上只是迭代传入MapMap.Entries并为每个Map.Entrythisthisthis )分别调用Region.put(key, value) ),则显然它并没有给您太多购买,当然也没有理由在将所有数据放入该区域之前将其存储在内存中。

For instance, most ResultSets are implemented with a DB cursor that allows you to fetch a certain number of rows at once, but not all the possible rows. 例如,大多数ResultSets都是使用DB游标实现的,该游标允许您一次获取一定数量的行,但并非所有可能的行。 Clearly, your SQL query can even be more selective about which rows are returned based on interests/pertinence, think of loading only a subset of the most important data, or some other criteria specifiable in the query predicate. 显然,您的SQL查询甚至可以根据兴趣/针对性更选择性地选择返回哪些行,可以考虑仅加载最重要数据的子集,或查询谓词中指定的某些其他条件。 Then simply just put the data into the Region when iterating the ResultSet . 然后,只需在迭代ResultSet时将数据放入Region中即可。

Food for thought. 值得深思。

-John -约翰

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM