ceph数据分布
ceph的存储是无主结构,数据分布依赖client来计算,有两个条主要路径。
1、数据到PG
2、PG 到OSD
有两个假设: 第一,pg的数量稳定,可以认为保持不变; 第二, OSD的数量可以增减,OSD的存储空间权重不等;
由于 PG的数量保持不变,由数据来找PGID的环节可以简单处理,对数据的key来取hash值再对pg的总数取模即可唯一确认pgid,pgid=hash(data_key)/pg_num。
难点在于从PG到OSD,如果直接用 hash(pgid)/osd_num的模式,则OSD有增减的时候数据就有无规律的迁移,并且也无法体现OSD的不同权重。
Crush算法就是来解决这个问题的,Crush目的是随机跳出一个OSD,并且要满足权重越大的OSD,挑中的概率越大。
每个OSD有不同的容量,比如是4T还是12T的容量,可以根据每个OSD的容量定义它的权重,以T为单位, 比如4T权重设为4,12T则设为12。
如何将PG映射到不同权重的OSD上面?这里可以直接采用CRUSH里面的Straw抽签算法。

核心步骤:
1)计算HASH
draw = CRUSH_HASH( PG_ID, OSD_ID, r ),其中把r当做一个常数,将PG_ID, OSD_ID一起作为输入,得到一个HASH值。
2)增加OSD权重
osd_straw =( draw &0xffff ) * osd_weight
draw &0xffff 得到一个0-65535的数字,再与OSD的权重相乘,以这个作为每个OSD的签长, 权重越大的,数值越大。
3)遍历选取最高的权重
high_draw
Crush所计算出的随机数,是通过HASH得出来,可以保障相同的输入会得出同样的输出结果。
这里只是计算得出了一个OSD,在Ceph集群中是会存在多个副本,如何解决一个PG映射到多个OSD的问题?
将常量r加1, 再去计算一遍,如果和之前的OSD编号不一样, 那么就选取它;如果一样的话,那么再把r+2,再重新计算,直到选出三个不一样的OSD编号。
如果样本容量足够大, 随机数对选中的结果影响逐渐变小, 起决定性的是OSD的权重,OSD的权重越大, 被挑选的概率也就越大。
样本容量足够大,到底是多大? 到底多大才能按照尽可能按照权重来分布,当然是尽量小的样本才好。
样本容量主要由PG和OSD的数量多少来决定,其中最关键的还是OSD数量,如果OSD很少(比如5块盘)也能尽量按照权重分布才好。
PG的数量主要是根据数据预估和OSD的数量来定,有个理论参考数,PG数量 =(OSD数量* 100)/副本数,但是PG数量少影响后面的扩容,太多又占用过多资源,需要有一个平衡。
基于上述考虑,写了一个很简单的程序来验证下数据分布平衡性。
假定OSD数量为5并且权重随机,PG的数量为5000。
结果1:
1.随机生成5个OSDID和对应权重
OSDID=I0N@6nt5pOhjY$g;权重=32.0
OSDID=.nIjl%3zs3aoE7K;权重=16.0
OSDID=S5O9bSS4NMo%qDN;权重=1.0
OSDID=t$lZF91ofuvOKcn;权重=24.0
OSDID=!E2Ia8XE^Jzb5Dz;权重=12.0
2.在pg数量为5000的时候,PG的分布结果:
OSDID=!E2Ia8XE^Jzb5Dz;权重=12.0;拥有的PG数量=625
OSDID=I0N@6nt5pOhjY$g;权重=32.0;拥有的PG数量=2682
OSDID=t$lZF91ofuvOKcn;权重=24.0;拥有的PG数量=1554
OSDID=.nIjl%3zs3aoE7K;权重=16.0;拥有的PG数量=139
结果2:
1.随机生成5个OSDID和对应权重
OSDID=C%EN$UM!e8nZy.R;权重=1.0
OSDID=1iTDBnZeeQ6^Uos;权重=32.0
OSDID=%EMc6a4V5cWi%7D;权重=2.0
OSDID=M7WKDUjLrQaV42D;权重=64.0
OSDID=7OVTO@l$XLE$OV$;权重=8.0
2.在pg数量为5000的时候,PG的分布结果:
OSDID=1iTDBnZeeQ6^Uos;权重=32.0;拥有的PG数量=1201
OSDID=7OVTO@l$XLE$OV$;权重=8.0;拥有的PG数量=18
OSDID=M7WKDUjLrQaV42D;权重=64.0;拥有的PG数量=3781
结果3:
1.随机生成5个OSDID和对应权重
OSDID=TSvabIIG#9IssWW;权重=12.0
OSDID=XglajmN2q3f5qRI;权重=0.8
OSDID=ZEeeX^Wp9tHaxuA;权重=0.5
OSDID=PSiiRAwddyc^ThW;权重=32.0
OSDID=nPI^YbDr0ttVzGa;权重=8.0
2.在pg数量为5000的时候,PG的分布结果:
OSDID=nPI^YbDr0ttVzGa;权重=8.0;拥有的PG数量=319
OSDID=PSiiRAwddyc^ThW;权重=32.0;拥有的PG数量=3816
OSDID=TSvabIIG#9IssWW;权重=12.0;拥有的PG数量=865
package com.test.zhangzk.crush;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;public class TestCephCrush {static String str = "abcdefghijklmnopqrstuvwxyzABCDEDFGHIJKLMNOPQRSTUVWXYZ0123456789.@!#$%^&*";static Float[] factories =new Float[] {0.25f,0.5F,0.8f,1f,2f,4f,8f,12f,16f,20f,24f,32f,64f};static int pgidCount = 5000;static int osdCount = 5;public static void main(String[] args) {List<String> pgidList = getRandomPgIdList(pgidCount);List<OSDBean> osdList = getRandomOSDIdList(osdCount);HashMap<String,Integer> keyCount = new HashMap<String,Integer>();for(int i=0;i<pgidCount;i++) {float maxStraw = 0.0f;float osdFactor = 0.0f;String osdId = "";for( int j=0;j<osdCount;j++) {String key = pgidList.get(i) + osdList.get(j);int hashCode = key.hashCode() & 0xffff;float straw = hashCode * osdList.get(j).getFactor();if( maxStraw < straw) {maxStraw = straw;osdFactor = osdList.get(j).getFactor();osdId = osdList.get(j).getId();}}String key = "OSDID="+osdId + ";权重=" + osdFactor;Integer v = keyCount.get(key);if( v == null ) {keyCount.put(key, 1);}else {keyCount.put(key, v+1);} }System.out.println("2.在pg数量为" + pgidCount +"的时候,PG的分布结果:");for(String k:keyCount.keySet()){System.out.println(k + ";拥有的PG数量=" +keyCount.get(k));}}private static List<String> getRandomPgIdList(int pgidCount){// TODO Auto-generated method stubList<String> pgidList = new ArrayList<String>();java.util.Random r = new Random(System.currentTimeMillis());for( int i=0;i<pgidCount;i++) {StringBuilder sb = new StringBuilder();for( int j=0;j<10;j++) {sb.append(str.charAt(r.nextInt(str.length()-1)));}pgidList.add(sb.toString());}return pgidList;}private static List<OSDBean> getRandomOSDIdList(int osdCount){System.out.println("1.随机生成"+ osdCount + "个OSDID和对应权重");// TODO Auto-generated method stubList<OSDBean> osdList = new ArrayList<OSDBean>();java.util.Random r = new Random(System.currentTimeMillis());for( int i=0;i<osdCount;i++) {StringBuilder sb = new StringBuilder();for( int j=0;j<15;j++) {sb.append(str.charAt(r.nextInt(str.length()-1)));}OSDBean osd = new OSDBean();osd.setId(sb.toString());osd.setFactor(factories[r.nextInt(factories.length)]);System.out.println( "OSDID=" + sb.toString()+ ";权重="+ osd.getFactor() );osdList.add(osd);}return osdList;}
}class OSDBean {private String id;private float factor;public String getId() {return id;}public void setId(String id) {this.id = id;}public float getFactor() {return factor;}public void setFactor(float factor) {this.factor = factor;}
}
相关文章:
ceph数据分布
ceph的存储是无主结构,数据分布依赖client来计算,有两个条主要路径。 1、数据到PG 2、PG 到OSD 有两个假设: 第一,pg的数量稳定,可以认为保持不变; 第二, OSD的数量可以增减,OSD的…...
mysql的两张表left join 进行关联后,索引进行优化案例
一 mysql的案例 1.1 不加索引情况 1.表1没加索引 2.表2没加索引 3.查看索引 1.2 添加索引 1.表1添加索引 2.表2添加索引 3.查看...
2018年3月全国计算机等级考试真题(语言二级C)
2018年3月全国计算机等级考试真题(语言二级C) 第1题 设有定义:char s[81];int i0;以下不能将一行带有空格的字符串正确读入的语句或语句组是 A. while((s[i]getchar())!\n);s[i]\0; B. scanf("%s",s); C.…...
java.util.Timer简介以及简单使用示例
一、简介 定时器(Timer)是一个工具类,用于安排任务(java.util.TimerTask)在指定时间后执行或以指定的时间间隔重复执行。它可以用于执行定时任务、定时调度和时间延迟等操作。 定时器(Timer)可以…...
C语言笔试训练【第12天】
文章目录 1、请阅读以下程序,其运行结果是( )2、假设编译器规定 int 和 short 类型长度分别为32位和16位,若有下列C语言语句,则 y 的机器数为( )3、下列程序的输出结果是什么( &…...
外网连接局域网的几种方式?快解析内网穿透安全便利吗?
外网连接局域网是一项网络连接中的关键技术,它能够让远程用户通过互联网访问内部局域网中的资源和服务。外网连接局域网为企业提供了更大的灵活性和便捷性,但也需要严格的安全措施来防止未经授权的访问。 外网连接局域网的几种方式 在将外网连接到局域…...
基于互斥锁的生产者消费者模型
文章目录 生产者消费者 定义代码实现 / 思路完整代码执行逻辑 / 思路 局部具体分析model.ccfunc(消费者线程) 执行结果 生产者消费者 定义 生产者消费者模型 是一种常用的 并发编程模型 ,用于解决多线程或多进程环境下的协作问题。该模型包含…...
USB隔离器电路分析,SA8338矽塔sytatek电机驱动,源特科技VPS8701,开关电源,电源 大师
一、 USB隔离器电路分析 进行usb隔离可以使用USB隔离模块 ADUM3160 ADUM4160 注意:B0505S 最大带载0.16A,副边需要带载能力需要改变方案 比如移动硬盘至少需要0.5A 用充电宝、18650、设计5V1A输出电源 二、 1A隔离电压方案...
TPC-DS 测试是否支持 Glue Data Catalog?
在上一篇文章《在Hive/Spark上执行TPC-DS基准测试 (PARQUET格式)》中,我们详细介绍了具体的操作方法,当时的集群使用的是Hive Metastore,所有操作均可成功执行。当集群启用 Glue Data Catalog 时,在执行add_constraints.sql时会报错: Optimizing table date_dim (1/24).…...
网络编程(8.14)TCP并发服务器模型
作业: 1. 多线程中的newfd,能否修改成全局,不行,为什么? 2. 多线程中分支线程的newfd能否不另存,直接用指针间接访问主线程中的newfd,不行,为什么? 多线程并发服务器模型原代码&…...
认识负载均衡||WEBSHELL
目录 一、负载均衡 1.nginx负载均衡算法 2.nginx反向代理-负载均衡 二、webshell 1.构造不含数字和字母的webshell 2.如何绕过 一、负载均衡 1.nginx负载均衡算法 (1)轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务&…...
Chapter 15: Object-Oriented Programming | Python for Everybody 讲义笔记_En
文章目录 Python for Everybody课程简介Object-oriented programmingManaging larger programsGetting startedUsing objectsStarting with programsSubdividing a problemOur first Python objectClasses as typesObject lifecycleMultiple instancesInheritanceSummaryGlossa…...
模板编程-成员特化
成员特化:类模板特化除了可以对整个类进行特化外,可以只针对某部分成员函数进行特化 全类特化和成员特化都属于全局特化 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring>template<typename T> class CMath { public:CMath(const…...
信安通用基础知识
文章目录 密码学经典误区PGP优良保密协议信安经典其它安全手段XSS与CSRF cross site request forgeryCSRF的利用逻辑CSRF示例CSRF防范检查Referer字段添加校验token XSS cross site scripting common weakness enumeration常见密码api误用(摘自毕设参考文献…...
网上购物系统的设计与实现/在线商城/基于spring boot的电商平台/基于Java的商品销售系统
摘 要 本毕业设计的内容是设计并且实现一个基于Springboot的网上购物系统。它是在Windows下,以MYSQL为数据库开发平台,Tomcat网络信息服务作为应用服务器。网上购物系统的功能已基本实现,主要包括用户管理、数码分类管理、数码产品管理、服…...
uniapp项目-配置store文件夹
1.创建store.js 说明:创建一个新的 Vuex Store 实例,配置 Store 中的模块。 import Vue from vue; import Vuex from vuex; // 导入两个 Vuex 模块:moduleCart 和 moduleUser import moduleCart from /store/cart.js; import moduleUser fr…...
element表格多选实现
表格实现多选 实现表格多选很简单,只需要在表格里加上一列即可,加完之后就会在表格里出现一列白色的四方块按钮,可以多选,也可以单选 <el-table-columntype"selection"width"55"align"center"&…...
宠物智能自动喂食器方案设计
据相关数据表明,2019年全国城镇宠物犬猫数量达到9915万只,增幅达到8.4%,消费市场规模达2024亿元,比2018年增长18.5%,整体呈现持续大幅增长的态势。而养宠人群的主力,为25岁至38岁年轻人,都市白领…...
学习笔记230818---对于promise失败状态处理的重要性
问题描述: 在项目中经常会出现如上的问题,这是因为,用promise封装的接口或第三方组件方法,如果只对成功的状态做处理,就会造成页面出错,报error。 解决方法 then()的末尾加上.catch(()>{})对失败的状态…...
【Redis】什么是缓存击穿,如何预防缓存击穿?
【Redis】什么是缓存击穿,如何预防缓存击穿? 缓存击穿是指一个 Key 非常热点,大并发集中对这一个点进行访问,当这个Key 在失效的瞬间,持续的大并发就会穿破缓存,直接请求数据库。缓存击穿和缓存雪崩的区别…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
