CAP 的小Demo

CAP 理论是分布式系统设计中的一个基本原则,它指出在一个分布式系统中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)这三个属性无法同时满足。

一致性(Consistency):在分布式系统中,一致性是指数据在多个副本之间保持一致的特性。即当一个数据副本被更新后,其他副本也必须被相应地更新,以保证数据的一致性。

可用性(Availability):可用性是指在分布式系统中,系统能够根据用户的请求正常响应并提供服务的能力。即系统需要时刻处于可用状态,能够处理用户的请求并返回正确的结果。

分区容错性(Partition Tolerance):分区容错性是指在分布式系统中,系统能够容忍网络分区(节点之间无法直接通信)的发生,并能够继续工作。即系统能够通过网络将节点连接起来,即使某些节点无法与其他节点直接通信。

根据 CAP 理论,由于网络分区是不可避免的,因此在分布式系统设计中,必须在一致性和可用性之间做出权衡,从而选择满足分区容错性的方案。具体来说,在网络分区发生时,系统可以选择保证一致性(C)和分区容错性(P),即 CP 模型;或者选择保证可用性(A)和分区容错性(P),即 AP 模型。

Nacos 是一个开源的服务注册与发现、配置管理平台。在 Nacos 的设计中,支持了两种部署模式:

CP 模式:在 CP 模式下,Nacos 保证了数据的一致性(Consistency)和分区容错性(Partition Tolerance)。当网络出现分区故障时,Nacos 将暂停对外提供服务,以保证数据的一致性。CP 模式适用于对数据一致性要求较高、可用性可以暂时降低的场景。

AP 模式:在 AP 模式下,Nacos 保证了可用性(Availability)和分区容错性(Partition Tolerance)。即使在网络分区的情况下,Nacos 仍然可以继续对外提供服务,但此时可能会出现数据同步延迟或不一致的情况。AP 模式适用于对可用性要求较高、对数据一致性要求相对较低的场景。

CAP:  C: consistence  一致性。 A: 可靠性 applicability   : P: 分区容错性
   最多能同时满足两个条件,不能三个都满足. 目前的分布式要么是满足AP  要么是CP
   kafka:  AP :能用  速度要快
   rabbitMQ : cp  金融系统  电商系统强调数据一致
   nacos 还是cp or ap?   默认为AP。

但是在我们工作中,如果使用nacos,有些应用场景需要使用AP不能够满足我们的需求,这个时候就需要我们使用CP来进行实现, 具体可以进行切换: 
    切换:curl -X PUT "http://localhost:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP"
          curl -X PUT "http://localhost:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=AP"    
    选用何种模式
        一般来说,如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模。当前主流的服务如Spring cloud和 Dubbo服务,都适
    用于AP模式。AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。
    如果需要在服务级别编辑或者存储配置信息,那么CP是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的使用V4L进行视频采集的demo代码,仅供参考: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <linux/videodev2.h> #define WIDTH 640 #define HEIGHT 480 #define BUFFER_COUNT 2 struct buffer { void* start; size_t length; }; int main(void) { int fd = open("/dev/video0", O_RDWR); if (fd < 0) { perror("open"); exit(1); } // 查询设备的功能和属性 struct v4l2_capability cap; if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { perror("VIDIOC_QUERYCAP"); exit(1); } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { fprintf(stderr, "The device does not support video capture.\n"); exit(1); } if (!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf(stderr, "The device does not support streaming I/O.\n"); exit(1); } // 设置视频格式 struct v4l2_format fmt; memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = WIDTH; fmt.fmt.pix.height = HEIGHT; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { perror("VIDIOC_S_FMT"); exit(1); } // 请求内存缓冲区 struct v4l2_requestbuffers reqbuf; memset(&reqbuf, 0, sizeof(reqbuf)); reqbuf.count = BUFFER_COUNT; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { perror("VIDIOC_REQBUFS"); exit(1); } // 映射内存缓冲区 struct buffer buffers[BUFFER_COUNT]; for (int i = 0; i < BUFFER_COUNT; i++) { struct v4l2_buffer buf; memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { perror("VIDIOC_QUERYBUF"); exit(1); } buffers[i].length = buf.length; buffers[i].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (buffers[i].start == MAP_FAILED) { perror("mmap"); exit(1); } if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { perror("VIDIOC_QBUF"); exit(1); } } // 启动视频流 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) { perror("VIDIOC_STREAMON"); exit(1); } // 从队列中取出缓冲区并处理 for (int i = 0; i < BUFFER_COUNT; i++) { struct v4l2_buffer buf; memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { perror("VIDIOC_DQBUF"); exit(1); } // 处理图像数据 // ... if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { perror("VIDIOC_QBUF"); exit(1); } } // 停止视频流 if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) { perror("VIDIOC_STREAMOFF"); exit(1); } // 释放内存缓冲区 for (int i = 0; i < BUFFER_COUNT; i++) { munmap(buffers[i].start, buffers[i].length); } close(fd); return 0; } ``` 以上代码仅供参考,具体实现可能因设备和操作系统而异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值