image-manage image-manage
首页
  • 介绍
  • 快速上手
  • 目录结构
  • 数据的存储
  • 数据的同步机制
GitHub (opens new window)
首页
  • 介绍
  • 快速上手
  • 目录结构
  • 数据的存储
  • 数据的同步机制
GitHub (opens new window)
目录

数据的同步机制

数据的同步在集群环境中至关重要,虽然image-manage已经避免在pod中使用单节点数据,控制各个pod状态一致,但是出于io性能的尝试,image-manage会每个节点都备份一份数据

# 1.1 image-manage启动同步

image-image启动会视情况选择复制一个pod内所有的数据或者在数据库表中进行数据比照,同步自己缺少的数据。

public  void startSy(){
        log.info("开始同步文件");
        String bestPod = podUtil.getBestPod();
        log.info("寻找最优同步节点:"+bestPod);

        String fileUrl = httpUtil.questProtocol+bestPod+dnsSuffix+":"+serverPort+ "?token="+PodDataSynConfig.SY_KEY_VALUE;
        // Send an HTTP GET request to the file URL
        byte[] fileData = httpUtil.getBytes(fileUrl);
        if (fileData != null) {
            FileUtil.unZip(fileData,imgFolderPath);
        }else {
            log.warn("无法获取最优节点文件,准备进行数据库扫表同步");
      }
        //开始数据库同步
        partSy();
    }
     public void partSy(){
        PodDataSynConfig.syedFlag = false;
        allFileName = FileUtil.listFilesInDirectory(imgFolderPath);
        log.info("开始扫表同步文件");
        List<ImageMetaDataAddFileName> imageMetaDataList = fileDao.getAllImg();
        if(imageMetaDataList != null){
            for(ImageMetaDataAddFileName imageMetaData : imageMetaDataList){
                if(!imageMetaData.getLocalUrl().contains(PodDataSynConfig.CURRENT_POD)){

                    Stack<String>stack = new Stack<>(){{
                        for(String pod :imageMetaData.getLocalUrl()){
                            push(pod);
                        }
                    }};
                    String metaFileName = imageMetaData.getMd5() + "." + FileUtil.splitFileNameAndExtension(imageMetaData.getImageName())[1];
                    byte[]array = accessServers(stack,metaFileName);
                    if(array != null){
                        File file = new File(imgFolderPath+"/"+metaFileName);
                        try(FileOutputStream fileOutputStream = new FileOutputStream(file)) {
                            fileOutputStream.write(array);
                            addPodRecord(new ImageMetaData(imageMetaData));
                        } catch (IOException e) {
                            log.warn("文件写入异常:=>"+imageMetaData.getMd5());
                            throw new RuntimeException();
                        }
                    }
                }

            }

        }

# 1.2 image-manage push同步

 @Async
    public void sendFile(MultipartFile file,String metaFileName){
        podUtil.flushPod();
        for(String pod : podUtil.getOthersPods()){
            String url = httpUtil.questProtocol +pod+dnsSuffix + ":" +serverPort +"/k8s/receiveImg";
            MultiValueMap<String, Object> body = null;
            try {
                body = getStringObjectMultiValueMap(file);
                body.add("metaFileName",metaFileName);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
            try {
                sendFile(url,requestEntity);
            } catch (Exception e) {
                log.error("推送到服务器url出错==>"+url);
            }
        }
    }

提示

如果某个pod接受到文件,pod会尝试把文件推送到其他pod中,确保数据一致

# 1.3 image-manage pull同步

 public boolean getMd5File(String md5FileName){
        podUtil.flushPod();
        Stack<String>stack = new Stack<>(){{
            for(String pod : podUtil.surPod){
                push(pod);
            }
        }};
        byte[]array = accessServers(stack,md5FileName);
        if(array != null){
            File file = new File(imgFolderPath+"/"+md5FileName);
            try(FileOutputStream fileOutputStream = new FileOutputStream(file)) {
                fileOutputStream.write(array);
            } catch (IOException e) {
               return false;
            }
        }
        fileDao.updateAddLocalUrl(md5FileName,PodDataSynConfig.CURRENT_POD);
        return true;
    }

提示

如果image-manage 发现请求中的image-manage文件没有,image-manage会向其他pod请求该文件。

# 1.4 定时扫表同步

提示

image-manage在启动后会生随机时间的定时任务,每24小时执行一次,确保至少每天进行一个扫表同步。

if(!PodDataSynConfig.initFlag){
            String hour = String.valueOf((int)(25 * Math.random()));
            ScheduleUtil.start(new ScheduleTask(UUID.randomUUID().toString(),new SyTaskServiceImpl()),String.format("0 0 %s * * ?",hour));
            log.info("创建数据库同步定时任务成功=>同步时间为:每日"+hour+":00");
        }

# 2.总结

注意

即便这样,这也并非一个经过检验成熟的方案,无法确保数据的万无一失

Theme by Vdoing | Copyright © 2019-2024 wnzzer | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式