821d2f98860e92a35042891f139fc15b8b5c0e66
\345\237\272\344\272\216k8s\345\256\236\347\216\260\345\205\203\346\225\260\346\215\256\347\232\204\345\220\214\346\255\245.md
... | ... | @@ -290,4 +290,74 @@ spec: |
290 | 290 | select {} |
291 | 291 | ``` |
292 | 292 | 通过上面的代码,我们可以实现对crd的watch功能,然后在事件处理方法中将app和models的关系存储到内存中,供后续的请求使用。 |
293 | -到此我们完成了基于k8s的元数据同步功能。 |
|
... | ... | \ No newline at end of file |
0 | +到此我们完成了基于k8s的元数据同步功能。 |
|
1 | + |
|
2 | + |
|
3 | +### 基于crd进行元模型内存同步 |
|
4 | + |
|
5 | +在上面的代码中,我们实现了对crd的watch功能,可知我们可以实时感知到crd中数据的变化,基于此特性,我们可以实现元模型数据在多个pod中的内存同步,下面使用java伪码示例: |
|
6 | +```java |
|
7 | + |
|
8 | +public interface AppModelEventHandler { |
|
9 | + void onAdd(AppModel appModel); |
|
10 | + void onUpdate(AppModel appModel); |
|
11 | + void onDelete(AppModel appModel); |
|
12 | +} |
|
13 | + |
|
14 | +class AppModelEventHandlerImpl implements AppModelEventHandler { |
|
15 | + /* |
|
16 | + 定义一个保存所有app模型元数据的ConcurrentHashMap |
|
17 | + key为app名称,value为另一个ConcurrentHashMap,key为model名称,值为模型元数据 |
|
18 | + */ |
|
19 | + private static final ConcurrentHashMap<String, ConcurrentHashMap<String, ModelMeta>> appModelMetaMap = new ConcurrentHashMap<>(); |
|
20 | + |
|
21 | + @Override |
|
22 | + public void onAdd(AppModel appModel) { |
|
23 | + // Handle the addition of an AppModel |
|
24 | + System.out.println("AppModel added: " + appModel); |
|
25 | + // 将app模型元数据添加到ConcurrentHashMap中 |
|
26 | + ConcurrentHashMap<String, ModelMeta> modelMetaMap = new ConcurrentHashMap<>(); |
|
27 | + for (AppModel.Model model : appModel.models) { |
|
28 | + String key = appModel.appName + "_" + model.name; |
|
29 | + // 从redis 获取模型元数据,并构建ModelMeta对象 |
|
30 | + ModelMeta modelMeta = new ModelMeta(); |
|
31 | + modelMetaMap.put(model.name, modelMeta); |
|
32 | + } |
|
33 | + } |
|
34 | + |
|
35 | + @Override |
|
36 | + public void onUpdate(AppModel appModel) { |
|
37 | + // Handle the update of an AppModel |
|
38 | + System.out.println("AppModel updated: " + appModel); |
|
39 | + // 更新app模型元数据 |
|
40 | + String appName = appModel.appName; |
|
41 | + String appVersion = appModel.version; |
|
42 | + // 判断 app名称是否存在,如果存在,则进一步判断app version是否与当前版本一致 |
|
43 | + // 如果一致,则说明没有更新,直接返回。 |
|
44 | + |
|
45 | + // 如果app version 不一致,则说明更新了版本号,需要更新模型元数据 |
|
46 | + // 遍历模型元数据,更新模型元数据 |
|
47 | + for (AppModel.Model model : appModel.models) { |
|
48 | + String key = appName + "_" + model.name; |
|
49 | + // 判断模型名称是否存在,如果存在,则继续判断模型版本号是否一致 |
|
50 | + // 如果一致,则说明没有更新,直接返回。 |
|
51 | + |
|
52 | + // 如果模型版本号不一致,则说明更新了版本号,需要更新模型元数据 |
|
53 | + |
|
54 | + // 从redis 获取模型元数据,并构建ModelMeta对象 |
|
55 | + ModelMeta modelMeta = new ModelMeta(); |
|
56 | + // 更新模型元数据 |
|
57 | + } |
|
58 | + |
|
59 | + } |
|
60 | + |
|
61 | + @Override |
|
62 | + public void onDelete(AppModel appModel) { |
|
63 | + // Handle the deletion of an AppModel |
|
64 | + System.out.println("AppModel deleted: " + appModel); |
|
65 | + } |
|
66 | +} |
|
67 | +``` |
|
68 | +在上面的代码中,我们定义了一个AppModelEventHandler接口,用于处理crd的增删改事件,然后在实现类中实现了对app模型元数据的增删改操作。一旦crd中数据发生变化,就会触发对应的事件处理方法,从而实现了元模型数据在多个pod中的内存同步。 |
|
69 | +需要注意的是,app和model 都是保存有自己的版本号,所以在更新的时候需要判断版本号是否一致,如果一致,则说明没有更新,直接返回即可,如果版本不一致则需要重新从redis加载最新版本的value。为什么要引入版本号version呢?主要是为了性能,因为k8s自带resync机制(为了解决事件消费失败问题),会将已有的数据以update事件定期重新同步到内存中,如果不判断版本号,则会导致每次都更新内存中的数据,且每次都需要从redis中获取value数据,造成很多无谓的性能浪费。 |
|
70 | + |