Install Redis Cluster(1master-2slave) on Kubernetes

news2024/11/20 10:40:08

目录

Node & Software & Docker Images Lists

Prerequisites

Architecture

Setting up your Redis cluster

Creating Namespace 

Creating StorageClass

Creating Persistent volumes

Creating ConfigMap 

Creating StatefulSet

Creating Headless Service

Testing Redis Cluster

Deploying Application 

Review

Reference documents


Node & Software & Docker Images Lists

HOSTNAME

IPNODE TYPECONFIG
master1192.168.1.100master4vCPU8G
Software NameVersion
kubeadmv1.26.0
kubectlv1.26.0
kubeletv1.26.0
cri-containerd-cni1.6.14
centos7.9
Image TypeVersion
k8sregistry.aliyuncs.com/google_containers/coredns:v1.9.3
registry.aliyuncs.com/google_containers/etcd:3.5.6-0
registry.aliyuncs.com/google_containers/kube-apiserver:v1.26.0
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.26.0
registry.aliyuncs.com/google_containers/kube-proxy:v1.26.0
registry.aliyuncs.com/google_containers/kube-scheduler:v1.26.0
registry.aliyuncs.com/google_containers/pause:3.9
calicodocker.io/calico/apiserver:v3.24.5
docker.io/calico/cni:v3.24.5
docker.io/calico/kube-controllers:v3.24.5
docker.io/calico/node:v3.24.5
docker.io/calico/pod2daemon-flexvol:v3.24.5
docker.io/calico/typha:v3.24.5
quay.io/tigera/operator:v1.28.5
redisdocker.io/library/redis:6.2.3-alpine
dashborddocker.io/kubernetesui/dashboard:v2.7.1
pythondocker.io/library/python:3.11.3

Prerequisites

Before we begin, there are a few things that you will need to make sure you have installed:

  1. Kubernetes Cluster
  2. Containerd

If you haven't installed,you could refer to this guide:Install Kubernetes 1.26 on Centos 7.9(Contianerd as CRI )_JJH的创世纪的博客-CSDN博客
 

Architecture

This article explores how to set up a Redis cluster (1 Master- 2 Slave) on Kubernetes and the architecture shown in the diagram below. We set StatefulSet as manager and run 3 redis-pods instances, create 1 Storageclass and 3 PVs, and a headless service exposed to other intranet pods that here is application-pod.

Setting up your Redis cluster

​Before you go much further, you should have a Kubernetes cluster up and running. This article makes use of Redis version 6. Follow the step-by-step instructions here, and your Redis cluster will be ready without any trouble. ​

You can download all files here.kubernetes-redis/redis-cluster-1master-2slave at main · ck784101777/kubernetes-redis · GitHub

Creating Namespace 

Create a namespace for a Redis server setup:

kubectl create namespace redis

 Then you can check it.

kubectl get pods -n redis

Creating StorageClass

​A storage class links to a provisioner, which is a plugin that can reserve disk space or purchase volumes to your cloud provider on your behalf. ​In this guide we uses persistent volume for the purposes of the demo with local storage (a file system folder). 

Create a storage class, which points to the local storage, using the following manifest code:

kubectl apply -f storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete

Then you can check it.(By the way,Storageclass as a kind of resources has no concept of namespace)

kubectl get storageclass

Creating Persistent volumes

Persistent volumes  (PVs) are used to create a storage size. In this demo, you will create a Redis cluster with three pods (one master and two slaves). Therefore, create three PVs.

The following code creates three PVs using the local storage provisioner:

kubectl apply -f pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-pv1
spec:
  storageClassName: redis-storage
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/storage/data1"

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-pv2
spec:
  storageClassName: redis-storage
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/storage/data2"

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-pv3
spec:
  storageClassName: redis-storage
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/storage/data3"
kubectl get pv
NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS    REASON   AGE
local-pv1   1Gi        RWO            Retain           Bound    redis/data-redis-0   local-storage            16h
local-pv2   1Gi        RWO            Retain           Bound    redis/data-redis-1   local-storage            16h
local-pv3   2Gi        RWO            Retain           Bound    redis/data-redis-2   local-storage            16h

 Creating ConfigMap 

The ConfigMap in the Kubernetes cluster is a key-value store. You can use the config information of Redis in the Kubernetes cluster as a ConfigMap. Get the full code of the ConfigMap manifest here redis-config.yaml. Download this file and save to your loacl system. 

One thing important is to change the password of master and slave with your desired password, which is needed for authentication. 

kubectl apply -n redis -f config.yaml

Creating StatefulSet

StatefulSet is the workload API object used to manage stateful applications such as Mysql、Oracle、Redis.

The StatefulSet offers ordered pod names starting from zero and recreates the pod with the same name whenever the pod dies or crashes. A pod can fail at any time. The persistent pod identifier uses this feature (recreating the pod with the same name) to match existing persistent volume (storage volume attached to the failed pod) to the newly created pod.

Create redis-statefulset.yaml which define a initContenter and run a series of shell commands.These commands aim at make a election strategy when master-pod down and following below diagram.

Node The command  of `redis slaveof` can turn the current server into a slave server of the specified server. The format is `slaveof hostip port` 

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      initContainers:
      - name: config
        image: redis:6.2.3-alpine
        command: [ "sh", "-c" ]
        args:
          - |
            cp /tmp/redis/redis.conf /etc/redis/redis.conf
            
            echo "finding master..."
            MASTER_FDQN=`hostname  -f | sed -e 's/redis-[0-9]\./redis-0./'`
            if [ "$(redis-cli -h sentinel -p 5000 ping)" != "PONG" ]; then
              echo "master not found, defaulting to redis-0"

              if [ "$(hostname)" == "redis-0" ]; then
                echo "this is redis-0, not updating config..."
              else
                echo "updating redis.conf..."
                echo "slaveof $MASTER_FDQN 6379" >> /etc/redis/redis.conf
              fi
            else
              echo "sentinel found, finding master"
              MASTER="$(redis-cli -h sentinel -p 5000 sentinel get-master-addr-by-name mymaster | grep -E '(^redis-\d{1,})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})')"
              echo "master found : $MASTER, updating redis.conf"
              echo "slaveof $MASTER 6379" >> /etc/redis/redis.conf
            fi
        volumeMounts:
        - name: redis-config
          mountPath: /etc/redis/
        - name: config
          mountPath: /tmp/redis/
      containers:
      - name: redis
        image: redis:6.2.3-alpine
        command: ["redis-server"]
        args: ["/etc/redis/redis.conf"]
        ports:
        - containerPort: 6379
          name: redis
        volumeMounts:
        - name: data
          mountPath: /data
        - name: redis-config
          mountPath: /etc/redis/
      volumes:
      - name: redis-config
        emptyDir: {}
      - name: config
        configMap:
          name: redis-config
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "redis-storage"
      resources:
        requests:
          storage: 500Mi
kubectl apply -n redis -f redis-statefulset.yaml
kubectl get pods -n redis
NAME      READY   STATUS    RESTARTS      AGE
redis-0   1/1     Running   1 (12m ago)   15h
redis-1   1/1     Running   1 (12m ago)   15h
redis-2   1/1     Running   0             23s

Then you can use `kubectl logs` to find how the election strategy run.As you can see,the "redis-0" was selected to Master,and "redis-1","redis-2" were selected to Slave.

[root@master1 ~]# kubectl logs -f -nredis redis-0 -c config
finding master...
Could not connect to Redis at sentinel:5000: Try again
master not found, defaulting to redis-0
this is redis-0, not updating config...
[root@master1 ~]# kubectl logs -f -nredis redis-1 -c config
finding master...
Could not connect to Redis at sentinel:5000: Try again
master not found, defaulting to redis-0
updating redis.conf...
[root@master1 ~]# kubectl logs -f -nredis redis-2 -c config
finding master...
Could not connect to Redis at sentinel:5000: Try again
master not found, defaulting to redis-0
updating redis.conf...

Next we try to delete "redis-2" and the StatefulSet recreate a new pod named "redis-2",too.And of cause , is still be seleted to Slave.By the way,we see log of "Could not connect to Redis at sentinel:5000:".This is because we dont set a redis-sentinel,the Sentinel node is implemented through k8s’ built-in failure recovery mechanism + the script in the StatefulSet configuration content.

[root@master1 ~]# kubectl delete pod -nredis redis-2
pod "redis-2" deleted
[root@master1 ~]# kubectl get pod -nredis
NAME      READY   STATUS     RESTARTS      AGE
curl      1/1     Running    2 (12m ago)   15h
redis-0   1/1     Running    1 (12m ago)   15h
redis-1   1/1     Running    1 (12m ago)   15h
redis-2   0/1     Init:0/1   0             2s
[root@master1 ~]# kubectl logs -f -nredis redis-2 -c config
finding master...
Could not connect to Redis at sentinel:5000: Name does not resolve
master not found, defaulting to redis-0
updating redis.conf...

Creating Headless Service

Headless services are usually used in conjunction with StatefulSet. Using headless services can expose breakpoints to other applications for their access .The  particularity is only internal pods can communicate with each other. Not exposed to applications outside the Kubernetes cluster

apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  clusterIP: None
  ports:
  - port: 6379
    targetPort: 6379
    name: redis
  selector:
    app: redis
kubectl apply -n redis -f redis-service.yaml
kubectl get service -n redis
NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
redis   ClusterIP   None         <none>        6379/TCP   16h

 If other pod run to access Headless Service,the can via domain name which is "redis.redis"(the full name is redis.redis.svc.cluster.local).And the single domain name of each redis-pod such as "redis-0" is "redis-0.redis.redis.svc.cluster.local"

[root@master1 nginx]# kubectl run curl --image=radial/busyboxplus:curl -it
If you don't see a command prompt, try pressing enter.

[ root@curl:/ ]$ nslookup redis.redis
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      redis.redis
Address 1: 10.244.137.99 redis-0.redis.redis.svc.cluster.local
Address 2: 10.244.137.116 redis-1.redis.redis.svc.cluster.local
Address 3: 10.244.137.114 redis-2.redis.redis.svc.cluster.loca

[ root@curl:/ ]$ nslookup redis-0.redis.redis.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      redis-0.redis.redis.svc.cluster.local
Address 1: 10.244.137.97 redis-0.redis.redis.svc.cluster.local

[ root@curl:/ ]$ nslookup redis-1.redis.redis.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      redis-1.redis.redis.svc.cluster.local
Address 1: 10.244.137.96 redis-1.redis.redis.svc.cluster.local

[ root@curl:/ ]$ nslookup redis-2.redis.redis.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      redis-2.redis.redis.svc.cluster.local
Address 1: 10.244.137.102 redis-2.redis.redis.svc.cluster.local

Testing Redis Cluster

Now we have created a Redis cluster with one master node and two slave nodes. Pod redis-0 will act as master node and pod redis-1 and redis-2 will act as slave nodes. You can check the log and description of redis-0.Or go inside the container to see the cluster information:

kubectl -n redis exec -it redis-0 -- sh

----
redis-cli 
auth a-very-complex-password-here
info replication

The figure above shows how many slaves the master is connected to, as well as the slave's IP address and other information.Similarly, you can check the log of the slave pod to see that the master and slave are connected successfully:

$kubectl -n redis exec -it redis-1 -- sh

---
redis-cli 
auth a-very-complex-password-here
info replication

Note that you can only write data on the master pod; slave pods are only for reading. So, log into the master pod and create some key-value data. Then check to see if the same data is replicated in the slave pod.

$kubectl -n redis exec -it redis-0 -- sh

--

redis-cli 
auth a-very-complex-password-here

SET name1 zhangsan
SET name1 lisi
SET name1 wangwu

$kubectl -n redis exec -it redis-1 -- sh

--

redis-cli 
auth a-very-complex-password-here

keys *

Deploying Application 

Now we going to Deploy a application which use python3 and import redis module.Code a simple sample to connect to redis and try read from redis cluster via "redis.redis:6379" and write to redis cluster via "0.redis.redis.svc.cluster.local:6379".(Don't forget replace your password)

import redis  

wredis_url = "redis-0.redis.redis.svc.cluster.local"
rredis_url = "redis.redis"
rr = redis.Redis(host=rredis_url, port=6379, decode_responses=True,password="Your password")  
wr = redis.Redis(host=wredis_url, port=6379, decode_responses=True,password="Your password")  
wr.set('age', '18')  
print(rr['age'])

 You could run a python image and following below test:

kubectl run application --image=docker.io/library/python:3.11.3  -it
--
pip3 install redis

cat <<EOF > ~/test.py
import redis  

wredis_url = "redis-0.redis.redis.svc.cluster.local"
rredis_url = "redis.redis"
rr = redis.Redis(host=rredis_url, port=6379, decode_responses=True,password="ck5590581.")  
wr = redis.Redis(host=wredis_url, port=6379, decode_responses=True,password="ck5590581.")  
wr.set('age', '18')  
print(rr['age'])
EOF

python3 ~/test.py
[OUTPUT]
18

Review

This article configures a redis cluster with one master and two slaves. The focus is on the configuration with StatefulSet. If you have experience, you may ask, where are the sentinel nodes deployed? This is a good question. In fact, in this configuration case, the Sentinel node is implemented through k8s’ built-in failure recovery mechanism + the script in the StatefulSet configuration content. Let's review the deployment process:

  • 1. Create a namespace. We don't want to expose the redis service to other applications in k8s. At the same time, creating a separate namespace helps manage resources, such as resource quotas (CPU, memory, IO)
  • 2-3. Section 2-3 describes how to create a persistent volume for redis. First, define a Storageclass. Use StorageClass to dynamically create PV according to PVC. Then we created a specific PV, and the creation of a PVC is not shown here, that is, it does not declare how the PV is used. The pv-pvc matching mechanism here is implemented by volumeClaimTemplates. By defining volumeClaimTemplates in Statefulset and specifying the Storageclass of volumeClaimTemplates as the created Storageclass, the pv-pvc relationship is dynamically established
  • 4. Created configMap to save redis configuration information
  • 5. Create a StatefulSet stateful service, the StatefulSet controller will create pods in order (starting from -0), and create the same pod name when the pod dies or restarts, the first pod will be assumed to be the master, and the others The pods will become slaves. Therefore, for a stateful application cluster, we need an ordered pod name, otherwise the pods will not be able to identify each other. And a master-slave election mechanism is added to StatefulSet, that is, redis-0 will be the master and others will be slaves. Since the pod is stateful, even if it dies
  • 6.Create a application with python3 and embed test code to check read and write to redis cluster.

In the example configuration in this article, the main pod (master) is only allowed to write data. This is because data synchronization cannot be handled if multiple pods are allowed to write data, the master pod will push the data changes to the slave pods and always stay in sync.

This approach ensures that data is replicated smoothly across all pods. The slave pods are used for data retrieval purposes only. , the first pod will be assumed to be the master, and the other pods will be slaves. Therefore, for a stateful application cluster, you need an ordered pod name.

However, Pods are assigned a random name in a Kubernetes deployment. Also, in order to match an existing persistent volume with a newly created pod, the same pod name is required whenever the pod is restarted.

A StatefulSet controller in a Kubernetes cluster will help you easily deploy stateful applications by giving each pod an ordered number starting from zero and creating the same pod name when the pod dies or restarts. The functionality provided by the StatefulSet controller is very much needed to set up a cluster environment for stateful applications.

Deploying stateful applications on a Kubernetes cluster has always been complicated. This article simplifies the complexities involved in deploying Redis Cluster.

Reference documents

Service | Kubernetes

K8S 快速入门(十六)实战篇:StorageClass(存储类)_犬豪的博客-CSDN博客

StatefulSets | Kubernetes

(十七)高并发redis学习笔记:3节点哨兵搭建_redis三节点的哨兵怎么配置_秦怀的博客-CSDN博客

redis之sentinel模式_redis sentinel_九千⑦的博客-CSDN博客

Redis哨兵服务器,检测主服务器宕机_JJH的创世纪的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中创|警惕AI骗局,10分钟被骗430万,AI诈骗正在全国爆发!

眼见为实&#xff1f;耳听为真&#xff1f;当心AI诈骗&#xff01; 只需要提供一张带脸的照片&#xff0c;就可以把自己置换成视频、电视剧中的男&#xff08;女&#xff09;主角&#xff0c;拟真度非常高&#xff0c;毫无违和感&#xff0c;这是最近爆火的AI换脸。 然而随着人…

浏览器数据存储方式

浏览器数据存储方式 常用的前端数据存储方法笼统来说有 3 种&#xff1a; local/session storagecookiesindexeddb 3 种方法各有各的优点和使用范围。 local/session storage local/session storage 保存的格式都为键值对&#xff0c;并且用法都是差不多&#xff0c;如下&…

如何选择高品质SPD浪涌保护器

了解了SPD的原理和技术参数和选型方法&#xff0c;但是面对市场上形形色色的SPD品牌&#xff0c;相差无几的参数&#xff0c;该如何去筛选高品质的SPD呢&#xff1f; 作为一个SPD开发人员&#xff0c;谈一下我的看法。前面提到&#xff0c;选择SPD时&#xff0c;有几个重要的参…

探索 Python Web 后端技术的发展之路

导语 Python 在 Web 后端开发领域中有着广泛的应用&#xff0c;它简洁的语法和强大的功能使得开发者们青睐有加。本文将更深入地探讨 Python Web 后端技术的发展趋势和路线&#xff0c;以及相关技术如何影响了 Web 开发的未来。 一、Python Web 框架的演变 Flask&#xff1a…

软件设计师 软件工程

** 判定覆盖 设置判定用例来保障真和假的结果都可以取到** 满足条件覆盖问题问需要多少个测试 ** 其实有技巧的&#xff08;就看最后面的 分支&#xff09;** **沟通路径&#xff1a;&#xff08;n-1&#xff09;n再/2 和主程序沟通那就是n-1条 ** ******************* 做题技…

HTTPS行为大赏(三分钟了解加密过程)

文章目录 前言1.没有加密的时候2.对称密钥加密传输3.非对称加密4.引入数字证书&#xff08;对称加密非对称加密&#xff09; 前言 既然要对HTTPS进行解读&#xff0c;我们首先了解&#xff0c;HTTPS是什么&#xff1f;HTTPS就相当于HTTPSSL/TLS这样的组合&#xff0c;HTTP&…

软考 软件设计师计算机网络笔记

网络设备 物理层的互联设备有中继器和集线器&#xff0c;集线器是一种特殊的多路多端口中继器 数据链路层的互连设备有网桥&#xff0c;交换机&#xff0c;交换机是一个多端口的网桥 网络层互连设备有路由器 协议簇 所有带T的除了TFTP其他都是TCP&#xff0c;所有不带T的除…

BFT 最前线 | ChatGPT登顶App Store;国产中文大语言模型「天河天元」发布;华为招募天才少年;阿里分拆上市

原创 | 文 BFT机器人 AI视界 TECHNOLOGY NEWS 01 ChatGPT上架App Store登顶榜首 OpenAI&#xff1a;很快也将出现在安卓上 近日&#xff0c;ChatGPT正式发布App版本&#xff0c;上架APP Store&#xff0c;支持iPhone和iPad设备。OpenAI表示&#xff0c;ChatGPT iOS APP可免费…

两阶段鲁棒优化及列与约束生成算法(CCG)的基本原理(超详细讲解,附matlab代码)

本文的主要参考文献&#xff1a; Zeng B , Zhao L . Solving Two-stage Robust Optimization Problems by A Constraint-and-Column Generation Method[J]. Operations Research Letters, 2013, 41(5):457-461. 1.两阶段鲁棒优化问题的引入 鲁棒优化是应对数据不确定性的一种优…

探索【Stable-Diffusion WEBUI】的图片超分辨插件:StableSR

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;图片放大&#xff08;二&#xff09;图片超分辨率放大脚本插件&#xff08;StableSR&#xff09;&#xff08;2.1&#xff09;下载组件&#xff08;2.2&#xff09;使用&#xff08;2.3&#xff09;实例对比…

bat脚本语法与实战

一、什么是bat脚本 bat脚本就是将一系列DOS命令按照一定顺序排列而形成的集合&#xff0c;运行在windows命令行环境上。通过本文的学习&#xff0c;基本可以实现一些简单的脚本。 二、为什么学习bat脚本&#xff1f; 使用bat可以提高办公效率&#xff0c;可以直接使用Notepad编…

JavaEE(系列12) -- 常见锁策略

目录 1. 乐观锁和悲观锁 2. 轻量级锁与重量级锁 3. 自旋锁和挂起等待锁 4. 互斥锁和读写锁 5. 可重入锁与不可重入锁 6. 死锁 6.1 死锁的必要条件 6.2 如何避免死锁 7. 公平锁和非公平锁 8. Synchronized原理及加锁过程 8.1 Synchronized 小结 8.2 加锁工作过程 8.2.1 偏向锁…

MySQL保证主备一致,如何解决循环复制?

备库只读&#xff0c;是如何和主库同步数据的&#xff1f; 你可能会问&#xff0c;我把备库设置成只读了&#xff0c;还怎么跟主库保持同步更新呢&#xff1f; 这个问题&#xff0c;你不用担心。因为 readonly 设置对超级 (super) 权限用户是无效的&#xff0c;而用于同步更新…

用Typescript 的方式封装Vue3的表单绑定,支持防抖等功能。

Vue3 的父子组件传值、绑定表单数据、UI库的二次封装、防抖等&#xff0c;想来大家都很熟悉了&#xff0c;本篇介绍一种使用 Typescript 的方式进行统一的封装的方法。 基础使用方法 Vue3对于表单的绑定提供了一种简单的方式&#xff1a;v-model。对于使用者来说非常方便&…

【011】C++选择控制语句 if 和 switch 详解

C控制语句之if和switch语句 引言一、选择控制语句if1.1、if 语句的形式1.2、if...else...语句的形式1.3、if...else if... else...语句 二、选择控制语句switch2.1、switch语句形式 三、switch和if...else if...else...比较四、注意事项总结 引言 &#x1f4a1; 作者简介&#…

企业工程行业管理系统源码-专业的工程管理软件-提供一站式服务

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示1…

Doo Prime 德璞资本:期货开户条件全解析!让你不再困惑!

期货市场是金融市场中一个非常重要的部分&#xff0c;对于许多投资者来说&#xff0c;期货市场是一个非常有吸引力的投资选择。然而&#xff0c;要进行期货交易&#xff0c;必须首先开设期货账户&#xff0c;这就需要满足一些期货开户条件&#xff0c;因此本文将介绍期货开户条…

认识SpringCloud(一) 注册中心Eureka

Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。在传统的rpc远程调用框架中&#xff0c;管理每个服务与服务之间依赖关系比较复杂&#xff0c;管理比较复杂&#xff0c;所以需要使用服务治理&#xff0c;管理服务于服务之间依赖关系&#xff0c;可以实现服…

(原创)getX+Dio实现Flutter悬浮置顶的页面效果

前言 Flutter的开发相对已经比较成熟了&#xff0c;现在市面上不少商业应用也在使用这个技术 老实说&#xff0c;Flutter去实现一些基础的ui界面&#xff0c;效率还是很高的 当然前提是你对它要有一定的了解。 今天就演示一下&#xff0c;如何去实现一个基础悬浮置顶的页面效果…

OSTrack 中的边界框回归策略

目录 一、裁剪和标签的设置 二、模型的预测输出的边界框回归 一、裁剪和标签的设置 1、添加偏移量&#xff0c;得到偏移后的边界框 jittered_anno [self._get_jittered_box(a, s) for a in data[s _anno]] 2、以偏移后的边界框为中心&#xff0c;进行裁剪 首先以偏移边界…