linux定时器王贤才,使用tgt搭建一个基于rbd的SCSI target

ceph作为一个统一存储方案,它通过rbd模块来对外提供块设备,目前对于rbd模块来说,它既有用户态的librbd也有内核态的krbd。而tgt作为用户层的SCSI target,支持通过librbd来访问ceph的块存储是一件水到渠成的事。最终由Dan Mick在tgt中加入了对rbd的支持,并在ceph社区发表了一篇文章,有兴趣的同学可以看看。

本篇文章介绍了如何使用stgt搭建一个基于rbd的SCSI target。

1.为了能在tgt中使用librbd访问ceph的块设备,需要tgt有相应的模块,你可以通过以下命令来确认。

$ tgtadm --lld iscsi --mode system --op show|grep rbd

rbd (bsoflags sync:direct)

如果有类似于上面的输出结果,说明你的tgt加载了rbd模块。该模块实际上是一个名为bs_rbd.so的动态链接库。如果命令没有输出,则说明你的tgt还不支持rbd,你需要安装最新的tgt,或者直接下载编译最新的源码。这里我给出从源码编译安装的步骤:

1.1 下载源代码

$ git clone

1.2 设置CEPH_RBD变量,使得tgt能够编译bs_rbd模块

$ export CEPH_RBD=1

1.3 在tgt源码的跟目录执行make

1.4 执行make install安装binaries

$ make install

1.5 再次检查tgt是否支持rbd

2. tgt能支持rbd之后,使用rbd命令创建一个镜像,搭建ceph环境的方法可以参见我的另一片博文——10分钟从源码编译到部署ceph环境,如有问题可以留言,共同探讨。

$ rbd create iscsi-image --size 4096

3. 创建一个scsi target

$ tgtadm --lld iscsi --mode target --op new --tid 1 --targetname iqn.2013-15.com.example:cephtgt.target0

4. 基于第二步创建的rbd image创建一个lun

$ tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 --backing-store iscsi-image --bstype rbd

5. 设置lun的访问控制

$ tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL

6. 通过iscsi initiator来确认是否lun是否已经创建好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于Transformer模型的Julia代码示例: ```julia using Flux using Flux.Data: DataLoader using Flux: onehot, crossentropy, throttle # 定义超参数 EMBED_SIZE = 256 HIDDEN_SIZE = 512 NUM_HEADS = 8 NUM_LAYERS = 6 DROPOUT = 0.1 BATCH_SIZE = 64 # 定义Transformer模型 struct Transformer embedding::Dense encoder::Chain decoder::Chain end function Transformer(vocab_size::Int, max_seq_len::Int; hidden_size=HIDDEN_SIZE, num_heads=NUM_HEADS, num_layers=NUM_LAYERS, dropout=DROPOUT) # 定义嵌入层 embedding = Dense(vocab_size, EMBED_SIZE) # 定义编码器 encoder_layer = TransformerLayer(hidden_size, num_heads, dropout) encoder = Chain([encoder_layer for i in 1:num_layers]...) # 定义解码器 decoder_layer = TransformerLayer(hidden_size, num_heads, dropout) decoder = Chain([decoder_layer for i in 1:num_layers]...) # 返回Transformer模型 Transformer(embedding, encoder, decoder) end # 定义一个Transformer层 struct TransformerLayer self_attention::MultiheadAttention feed_forward::Chain dropout1::Dropout dropout2::Dropout layer_norm1::LayerNorm layer_norm2::LayerNorm end function TransformerLayer(hidden_size::Int, num_heads::Int, dropout::Float64) # 定义自注意力层 self_attention = MultiheadAttention(hidden_size, hidden_size, num_heads) # 定义前馈网络 feed_forward = Chain(Dense(hidden_size, hidden_size, relu), Dense(hidden_size, hidden_size)) # 定义dropout层和layer normalization层 dropout1 = Dropout(dropout) dropout2 = Dropout(dropout) layer_norm1 = LayerNorm(hidden_size) layer_norm2 = LayerNorm(hidden_size) # 返回TransformerLayer TransformerLayer(self_attention, feed_forward, dropout1, dropout2, layer_norm1, layer_norm2) end # Transformer层的前向传播 function (layer::TransformerLayer)(x, mask) # 多头自注意力 attention_out = layer.self_attention(x, x, x, mask) # Add & Norm x = layer_norm1(x + layer.dropout1(attention_out)) # 前馈网络 ff_out = layer.feed_forward(x) # Add & Norm x = layer_norm2(x + layer.dropout2(ff_out)) # 返回Transformer层的输出 x end # Transformer模型的前向传播 function (model::Transformer)(src, tgt) # 嵌入源序列和目标序列 src_emb = model.embedding(src) tgt_emb = model.embedding(tgt) # 定义掩码 src_pad_mask = src .== 0 tgt_pad_mask = tgt .== 0 tgt_len = size(tgt, 2) tgt_sub_mask = Flux.tril!(ones(tgt_len, tgt_len)) tgt_mask = reshape(tgt_sub_mask, 1, tgt_len, tgt_len, 1) .| reshape(tgt_pad_mask, size(tgt, 1), 1, 1, tgt_len) # 编码源序列 enc_out = model.encoder(src_emb, src_pad_mask) # 解码目标序列 dec_out = model.decoder(tgt_emb, enc_out, tgt_mask, tgt_pad_mask) # 返回解码器的输出 dec_out end # 定义多头自注意力层 struct MultiheadAttention wq::Dense wk::Dense wv::Dense linear::Dense num_heads::Int end function MultiheadAttention(hidden_size::Int, key_size::Int, num_heads::Int) # 计算每个头的维度 head_size = div(hidden_size, num_heads) # 定义权重矩阵 wq = Dense(hidden_size, key_size * num_heads) wk = Dense(hidden_size, key_size * num_heads) wv = Dense(hidden_size, hidden_size * num_heads) linear = Dense(hidden_size * num_heads, hidden_size) # 返回MultiheadAttention层 MultiheadAttention(wq, wk, wv, linear, num_heads) end # 多头自注意力层的前向传播 function (layer::MultiheadAttention)(xq, xk, xv, mask) # 计算batch size和sequence length bsz, len_q, _ = size(xq) _, len_k, _ = size(xk) _, len_v, _ = size(xv) # 将输入张量的最后一维分成num_heads个维度 q = reshape(layer.wq(xq), bsz, len_q, layer.num_heads, :) k = reshape(layer.wk(xk), bsz, len_k, layer.num_heads, :) v = reshape(layer.wv(xv), bsz, len_v, layer.num_heads, :) # 转置第2个和第3个维度 q = permutedims(q, (1, 3, 2, 4)) k = permutedims(k, (1, 3, 2, 4)) v = permutedims(v, (1, 3, 2, 4)) # 定义掩码 mask = reshape(mask, bsz, 1, len_q, len_k) # 计算注意力分数 scores = einsum("b h i d, b h j d -> b h i j", q, k) / sqrt(size(q, end)) # 应用掩码 if mask != nothing scores = mask .* scores .+ (1 .- mask) .* -Inf end # 计算注意力权重 attn_weights = softmax(scores, dims=4) # Dropout attn_weights = dropout(attn_weights, 0.1) # 计算上下文张量 context = einsum("b h i j, b h j d -> b h i d", attn_weights, v) # 将上下文张量展开成2维张量 context = reshape(context, bsz, len_q, layer.num_heads * size(v, end)) # 线性变换 linear_out = layer.linear(context) # 返回MultiheadAttention层的输出 linear_out end # 加载数据集 train_data, test_data = Flux.Data.MNIST.traindata(Float32) train_data = DataLoader(train_data, batchsize=BATCH_SIZE, shuffle=true) # 定义损失函数和优化器 loss(x, y) = crossentropy(model(x, x), y) opt = ADAM() # 训练模型 model = Transformer(784, 28, hidden_size=256, num_layers=4) for epoch in 1:10 for (x, y) in train_data Flux.back!(loss, x, y) Flux.update!(opt, params(model)) end end ``` 请注意,这只是一个示例代码,并且可能需要根据您的特定用例进行修改。此外,为了使代码更易于理解,省略了某些细节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值