商店网站制作,地方门户网站策划书,百度旗下推广平台有哪些,设计效果图怎么做ceph的存储是无主结构#xff0c;数据分布依赖client来计算#xff0c;有两个条主要路径。
1、数据到PG
2、PG 到OSD
有两个假设#xff1a; 第一#xff0c;pg的数量稳定#xff0c;可以认为保持不变#xff1b; 第二#xff0c; OSD的数量可以增减#xff0c;OSD的…ceph的存储是无主结构数据分布依赖client来计算有两个条主要路径。
1、数据到PG
2、PG 到OSD
有两个假设 第一pg的数量稳定可以认为保持不变 第二 OSD的数量可以增减OSD的存储空间权重不等
由于 PG的数量保持不变由数据来找PGID的环节可以简单处理对数据的key来取hash值再对pg的总数取模即可唯一确认pgidpgidhash(data_key)/pg_num。
难点在于从PG到OSD如果直接用 hash(pgid)/osd_num的模式则OSD有增减的时候数据就有无规律的迁移并且也无法体现OSD的不同权重。
Crush算法就是来解决这个问题的Crush目的是随机跳出一个OSD并且要满足权重越大的OSD挑中的概率越大。
每个OSD有不同的容量比如是4T还是12T的容量可以根据每个OSD的容量定义它的权重以T为单位 比如4T权重设为412T则设为12。
如何将PG映射到不同权重的OSD上面这里可以直接采用CRUSH里面的Straw抽签算法。 核心步骤
1计算HASH
draw CRUSHHASH PGID OSDID r )其中把r当做一个常数将PGID OSDID一起作为输入得到一个HASH值。
2增加OSD权重
osdstraw draw 0xffff osdweight
draw 0xffff 得到一个0-65535的数字再与OSD的权重相乘以这个作为每个OSD的签长 权重越大的数值越大。
3遍历选取最高的权重
high_draw
Crush所计算出的随机数是通过HASH得出来可以保障相同的输入会得出同样的输出结果。
这里只是计算得出了一个OSD在Ceph集群中是会存在多个副本如何解决一个PG映射到多个OSD的问题
将常量r加1 再去计算一遍如果和之前的OSD编号不一样 那么就选取它如果一样的话那么再把r2再重新计算直到选出三个不一样的OSD编号。
如果样本容量足够大 随机数对选中的结果影响逐渐变小 起决定性的是OSD的权重OSD的权重越大 被挑选的概率也就越大。
样本容量足够大到底是多大 到底多大才能按照尽可能按照权重来分布当然是尽量小的样本才好。
样本容量主要由PG和OSD的数量多少来决定其中最关键的还是OSD数量如果OSD很少比如5块盘也能尽量按照权重分布才好。
PG的数量主要是根据数据预估和OSD的数量来定有个理论参考数PG数量 OSD数量* 100/副本数但是PG数量少影响后面的扩容太多又占用过多资源需要有一个平衡。 基于上述考虑写了一个很简单的程序来验证下数据分布平衡性。
假定OSD数量为5并且权重随机PG的数量为5000。 结果1:
1.随机生成5个OSDID和对应权重
OSDIDI0N6nt5pOhjY$g;权重32.0
OSDID.nIjl%3zs3aoE7K;权重16.0
OSDIDS5O9bSS4NMo%qDN;权重1.0
OSDIDt$lZF91ofuvOKcn;权重24.0
OSDID!E2Ia8XE^Jzb5Dz;权重12.0
2.在pg数量为5000的时候PG的分布结果
OSDID!E2Ia8XE^Jzb5Dz;权重12.0;拥有的PG数量625
OSDIDI0N6nt5pOhjY$g;权重32.0;拥有的PG数量2682
OSDIDt$lZF91ofuvOKcn;权重24.0;拥有的PG数量1554
OSDID.nIjl%3zs3aoE7K;权重16.0;拥有的PG数量139 结果2:
1.随机生成5个OSDID和对应权重
OSDIDC%EN$UM!e8nZy.R;权重1.0
OSDID1iTDBnZeeQ6^Uos;权重32.0
OSDID%EMc6a4V5cWi%7D;权重2.0
OSDIDM7WKDUjLrQaV42D;权重64.0
OSDID7OVTOl$XLE$OV$;权重8.0
2.在pg数量为5000的时候PG的分布结果
OSDID1iTDBnZeeQ6^Uos;权重32.0;拥有的PG数量1201
OSDID7OVTOl$XLE$OV$;权重8.0;拥有的PG数量18
OSDIDM7WKDUjLrQaV42D;权重64.0;拥有的PG数量3781 结果3:
1.随机生成5个OSDID和对应权重
OSDIDTSvabIIG#9IssWW;权重12.0
OSDIDXglajmN2q3f5qRI;权重0.8
OSDIDZEeeX^Wp9tHaxuA;权重0.5
OSDIDPSiiRAwddyc^ThW;权重32.0
OSDIDnPI^YbDr0ttVzGa;权重8.0
2.在pg数量为5000的时候PG的分布结果
OSDIDnPI^YbDr0ttVzGa;权重8.0;拥有的PG数量319
OSDIDPSiiRAwddyc^ThW;权重32.0;拥有的PG数量3816
OSDIDTSvabIIG#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) {ListString pgidList getRandomPgIdList(pgidCount);ListOSDBean osdList getRandomOSDIdList(osdCount);HashMapString,Integer keyCount new HashMapString,Integer();for(int i0;ipgidCount;i) {float maxStraw 0.0f;float osdFactor 0.0f;String osdId ;for( int j0;josdCount;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 OSDIDosdId ;权重 osdFactor;Integer v keyCount.get(key);if( v null ) {keyCount.put(key, 1);}else {keyCount.put(key, v1);} }System.out.println(2.在pg数量为 pgidCount 的时候PG的分布结果);for(String k:keyCount.keySet()){System.out.println(k ;拥有的PG数量 keyCount.get(k));}}private static ListString getRandomPgIdList(int pgidCount){// TODO Auto-generated method stubListString pgidList new ArrayListString();java.util.Random r new Random(System.currentTimeMillis());for( int i0;ipgidCount;i) {StringBuilder sb new StringBuilder();for( int j0;j10;j) {sb.append(str.charAt(r.nextInt(str.length()-1)));}pgidList.add(sb.toString());}return pgidList;}private static ListOSDBean getRandomOSDIdList(int osdCount){System.out.println(1.随机生成 osdCount 个OSDID和对应权重);// TODO Auto-generated method stubListOSDBean osdList new ArrayListOSDBean();java.util.Random r new Random(System.currentTimeMillis());for( int i0;iosdCount;i) {StringBuilder sb new StringBuilder();for( int j0;j15;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;}
}