RAID的介绍、使用以及监控

1945a4459fb850711cac177047f46820.gif

新钛云服已累计为您分享821篇技术干货

bb9d6cb9b554cb41e1573183349ba61f.gif

RAID详解

简介

背景:因为当时CPU的速度增长很快,而磁盘驱动器的数据传输速率无法大幅提高,所以需要有一种方案解决二者之间的矛盾。

所以raid的方案就诞生,raid是由很多廉价的磁盘,组合成一个容量巨大的磁盘组,在RAID中,可以让很多磁盘驱动器同时传输数据,而这些磁盘驱动器在逻辑上又是一个磁盘驱动器,所以使用RAID可以达到单个的磁盘驱动器几倍、几十倍甚至上百倍的速率,RAID最后成功解决了磁盘驱动器的数据传输速率的问题。

分类

一是外接式磁盘阵列柜、二是内接式磁盘阵列卡,三是利用软件实现

外接式磁盘阵列柜是一种独立的存储设备,可以通过外部接口(如 USB、eSATA、Thunderbolt 等)连接到计算机或其他服务器,适合个人用户、小型办公室或作为备份解决方案,在此不展开讨论。

内接式磁盘阵列卡是安装在计算机内部的硬件设备,直接连接到主板的 PCIe 插槽,并管理连接到它的硬盘。raid卡可以提供更多的 RAID 配置选项和高级功能,如缓存、电池后备写入缓存(BBU)等

软件 RAID 是通过操作系统或独立的软件来管理硬盘的 RAID 配置,如mdadm,LVM2,成本较低,配置灵活。

级别

常见的有:RAID 0,RAID 1,RAID 5,RAID 6,RAID 10

7eeebca29b76c0f7239faa766a4d0b2f.png

RAID 0(至少需要两块盘)

RAID 0是以条带化的方式,分别向两块盘,并行地写入数据,读取时也是并行的。一方面,并行操作可以充分利用I/O总线的**带宽**,提高磁盘整体存取性能;另一方面,它有RAID级别中最高的空间利用率,但是没有数据冗余,存在单点故障。

726cfd2fc9f4c77b40e3713b36a7bb11.png

RAID 1(至少需要2块硬盘,一般为双数)

RAID 0是以镜像的方式,分别向两块盘,并行写入相同的数据。有数据冗余,可靠性强,一半写数据,一半用来做备份,但是硬盘容量会减少一半。读取时,从两块硬盘上并行读取,写入慢,读取快。

04cfb1236c5f6dcb0f01962f5b938fbb.png

RAID 5(需要3块以上硬盘)

RAID 5采用奇偶校验,可靠性强,磁盘校验和被散列到不同的磁盘里面,增加了读写速率。只有当两块磁盘同时丢失时,数据才无法恢复,至少三块硬盘并且硬盘大小应该相等才能组成Raid 5阵列

aa5fe210674ae2e38dec9c472ccce965.png

RAID使用

软raid

mdadm是multiple devices admin的简称,它是Linux下的一款标准的软件 RAID 管理工具

安装:

#直接用yum\apt安装即可
yum install mdadm

常用参数:

71b5168f66daec06b79693bca6f42464.png

mdadm工具指令基本格式:

mdadm -C -v 目录 -l 级别 -n 磁盘数量 设备路径
举例:
mdadm -C -v /dev/md0 -l 0 -n 2 /dev/sda1 /dev/sdb1
 //在/dev/md0目录下将sda1与sdb1两块磁盘创建为RAID级别为0,磁盘数为2的RAID0阵列

创建流程

1.使用 lsblk 命令查看可用的磁盘:

lsblk

2、使用 mdadm 命令创建 RAID 0 阵列:

mdadm -C -v /dev/md0 -l 0 -n 2 /dev/sda /dev/sdb

需要将 /dev/sda 和 /dev/sdb 替换为您的磁盘名称。

#检查/dev/md0设备是否已经正确创建并且处于“活动”状态
mdadm --detail /dev/md0

3.格式化 RAID 0 阵列:

mkfs.ext4 /dev/md0

4.挂载 RAID 0 阵列:

mkdir /mnt/raid0
mount /dev/md0 /mnt/raid0(临时挂载)

硬raid

Raid卡市场主要是LSI、Adaptec、Highpoint、Promise等厂商提供。Adaptac被PMC收购后,提供的Raid卡即为PMC,简称为P卡。LSI公司提供的Raid卡,即为L卡。

查看raid卡的类型可以使用 lspci | grep -i raid命令。

PMC配置操作工具为:arcconf,LSI配置操作工具为:MegaCli、storcli。本文仅讨论MegaCli工具的使用

安装

MegaCli 安装脚本

#!/bin/bash
#下载安装包
wget --user=hetzner --password=download <http://download.hetzner.de/tools/LSI/tools/MegaCLI/8.07.14_MegaCLI.zip>


# 获取操作系统 ID
os_id=$(grep -oP '^ID=\\K.*' /etc/os-release)
# 判断操作系统并执行相应的命令
if [ "$os_id" = "debian" ]; then
    apt install unzip alien libncurses5 -y
    unzip -d ./megacli 8.07.14_MegaCLI.zip
    cd ./megacli/Linux/
    alien MegaCli-8.07.14-1.noarch.rpm
    dpkg -i megacli_8.07.14-2_all.deb  
    echo "MegaCLI安装成功"
elif [ "$os_id" = '"centos"' ] || [ "$os_id" = '"rocky"' ]; then
    yum install unzip  -y
    unzip -d ./megacli 8.07.14_MegaCLI.zip
    cd ./megacli/Linux/
    rpm -ivh MegaCli-8.07.14-1.noarch.rpm 
    echo "MegaCLI安装成功"
else
    echo "操作系统不符,已退出"
    exit 1
fi

MegaCli常用命令

# 查看raid卡信息
/opt/MegaRAID/MegaCli/MegaCli64 -AdpAllInfo -aALL
# 查看所有 raid 级别
/opt/MegaRAID/MegaCli/MegaCli64 -LDInfo -Lall -aALL 
# 查看所有硬盘状态
/opt/MegaRAID/MegaCli/MegaCli64  -PDList -aALL 
/opt/MegaRAID/MegaCli/MegaCli64  -PDList -aALL | grep 'Firmware state'
#删除raid (注意这里L1的数字为Target Id的数字)
/opt/MegaRAID/MegaCli/MegaCli64 -CfgLdDel -L1 -a0

创建流程

1.查看所有硬盘的信息

/opt/MegaRAID/MegaCli/MegaCli64 -PDList -aALL

03406ea2a975f3b4f4fd6719601651af.png

常见参数含义

Medai Error Count 不为0,表示磁盘可能错误,可能是磁盘有坏道,数值越大,危险系数越高

Other Error Count 不为0,表示磁盘可能存在松动,可能需要重新再插入

Firmware state: 磁盘的状态,Online是最好的状态,除此之外还有 Unconfigured、Offline、Failed

2.根据磁盘数量创建raid

/opt/MegaRAID/MegaCli/MegaCli64 -CfgLdAdd -rX [Enclosure:Slot,...] [WT|WB] [NORA|RA] [Direct|Cached]
-r:指定raid级别
WB:写缓存策略
WT:直接写入磁盘,不适用RAID卡缓存                       
Direct:读操作不缓存到RAID卡缓存
Cached:读操作缓存到RAID卡缓存
举例:创建一个包括4块盘的raid0,写缓存策略,自适应预读,不缓存到RAID卡缓存
/opt/MegaRAID/MegaCli/MegaCli64 -CfgLdAdd -r0 [0:0,0:1,0:2,0:3] WB Direct -a0

3.查看raid和磁盘的状态

#查看raid的状态
/opt/MegaRAID/MegaCli/MegaCli64 -LDInfo -Lall -aALL
#查看磁盘的状态
/opt/MegaRAID/MegaCli/MegaCli64  -PDList -aALL | grep 'Firmware state'

RAID监控

通过脚本监控硬raid状态

#!/bin/bash  
#配置告警信息
TIME=$(date +'%Y-%m-%d %H:%M:%S')
HOST=$(hostname)
IP="`hostname -I | awk 'BEGIN{FS=" "}{print $1}'`"
logfile=/logs/check_megacli.log


# Telegram信息
t_token='xxxxx'
t_chat_ID="xxxxx"
t_url='https://api.telegram.org/bot'xxxx'/sendMessage' 


# Telegram通知函数
function send_telegram() {
    local msg="$1"
    local formatted_msg=$(echo -e "$msg")
    curl -s -X POST "$t_url" -d chat_id="$t_chat_ID" -d text="$formatted_msg" -d parse_mode="$t_mode"
}


# 定义 MegaCli64 的路径  
MEGACLI_PATH="/opt/MegaRAID/MegaCli/MegaCli64"  


# 获取 RAID 状态  
raid_status=$($MEGACLI_PATH -LDInfo -Lall -aALL | grep -i "State" | awk '{print $NF}')
echo "$raid_status" > /tmp/raidstate.log 
# 获取硬盘状态  
disk_status=$($MEGACLI_PATH -pdlist -aALL  | grep "Firmware state" | awk -F : '{print $2}' | awk -F , '{print $1}') 
echo "$disk_status" > /tmp/fireware.log


# 检查 RAID 状态
for i in `cat < /tmp/raidstate.log`  
do
if [[ "$i" != "Optimal" ]]; then  
    echo "$current_time - RAID 状态异常: $raid_status" >> $logfile
    # 发送Telegram告警
    send_telegram "时间: $(date +'%Y-%m-%d %H:%M:%S')\n服务器: $(hostname)\nIP: $(hostname -I | awk '{print $1}')\n告警信息: RAID状态:$i,请立即检查!\n报错详细信息: /logs/check_megacli.log" 
fi  
done


# 检查硬盘状态  
for i in `cat < /tmp/fireware.log`
do
if [[ "$i" != "Online" ]]; then  
    echo "$current_time - 硬盘状态异常: $i" >> $logfile  
    # 发送Telegram告警
    send_telegram "时间: $(date +'%Y-%m-%d %H:%M:%S')\n服务器: $(hostname)\nIP: $(hostname -I | awk '{print $1}')\n告警信息: RAID状态:$i,请立即检查!\n报错详细信息: /logs/check_megacli.log"
fi  
done

通过脚本监控软raid状态

#!/bin/bash


TIME=$(date +'%Y-%m-%d %H:%M:%S')
HOST=$(hostname)
IP="`hostname -I | awk 'BEGIN{FS=" "}{print $1}'`"
logfile=/logs/check_mdadm.log


# 钉钉
token="xxxx"
dingtalk_url="https://oapi.dingtalk.com/robot/send?access_token=$token"


# Telegram
t_chat_ID="xxxx"
t_mode='HTML'
t_url='https://api.telegram.org/bot"xxxx"/sendMessage'  


# 钉钉通知函数
function send_dingtalk() {
local msg="$1"
local json_payload=$(cat <<EOF
{
    "msgtype": "text", 
    "text": {
        "content": "时间: $TIME\n服务器: $HOST\nIP: $IP\n告警信息: $msg\n报错日志路径: /logs/check_mdadm.log"
    },
    "at": {
        "isAtAll": false
    }
}
EOF
)
    curl -X POST "$dingtalk_url" \
         -H 'Content-Type: application/json' \
         -d "$json_payload"


}


# Telegram通知函数
function send_telegram() {
    local msg="$1"
    local formatted_msg=$(echo -e "$msg")
    curl -s -X POST "$t_url" -d chat_id="$t_chat_ID" -d text="$formatted_msg" -d parse_mode="$t_mode"
}


hostname=`hostname`
cd /dev
list=`ls md?`


if [ ! -n "$list" ] ; then
    exit
fi
#主循环
for name in $list ; do
    subject=`/sbin/mdadm -D /dev/$name |grep "State :"`
    num1=`echo $subject |grep degraded |wc -l`
    num2=`echo $subject |grep FAILED |wc -l`
    num3=`echo $subject |grep clean |wc -l`
    status="`sudo mdadm --detail /dev/md? | grep -e "State : " | awk 'BEGIN{FS=":"}{print $2}' | uniq`"
    remark=$(GetRemark /tmp/$name-lastsend)


  if [ $num1  -ne 0 ] || [ $num2 -ne 0 ] ; then
        echo -e " \e[31m Hello World \e[0m"
        echo -e "$hostname $name \e[31m Error \e[0m  $subject"
        if [ "$remark" =  "" ] ; then
            /sbin/mdadm -D $name  > /tmp/disk_result.txt
            disklist=`ls /dev/sd?`


            for disk in $disklist ; do
                echo $disk >> /tmp/disk_result.txt
                smartctl -a $disk |grep Serial >> /tmp/disk_result.txt
            done


        # 发送钉钉告警
        send_dingtalk "主机RAID状态:$status,请立即检查!"


        # 发送Telegram告警
        #send_telegram "时间: $(date +'%Y-%m-%d %H:%M:%S')\n服务器: $(hostname)\nIP: $(hostname -I | awk '{print $1}')\n告警信息: 主机RAID状态:$status,请立即检查!\n报错详细信息: /logs/check_mdadm.log"
        fi      


    elif [ $num3 -eq 1 ] ; then
        echo -e "$(date +'%Y-%m-%d %H:%M:%S')  $hostname $name \e[34m OK \e[0m   $subject" >>$logfile
  fi  
done

附录

遇到的问题

1、在对RAID组扩容时,热添加的扩容盘意外下线,导致文件系统损坏,不能读写,raid状态变成了Offline

热添加的盘在重构期间应保持在线,以确保数据完整性和系统稳定性。如果意外将热添加的盘下线,会导致整个raid中的所有硬盘下线,无法读写

如果意外下线了,如何进行恢复文件系统

首先将原有的硬盘重新上线,此时raid的状态恢复为Optimal,但是文件系统仍然有问题,不能读写

/opt/MegaRAID/MegaCli/MegaCli64 -PDOnline -PhysDrv [0:0,0:1,0:2,0:3] -a0

接着将挂载的文件目录卸载掉

umount /data

然后利用fsck修复损坏的文件系统(通常用于检查 ext2、ext3 或 ext4 文件系统)

fsck -y /dev/sda

如果是xfs的文件系统使用xfs_repair

xfs_repair /dev/sda

修复完成后重新挂载,检查状态

如果你运行fsck或xfs_repair命令(文件系统检查和修复命令),它也许会找到一些数据碎片,这些文件碎片在硬盘中并没有引用。特别的,fsck也许能找到看起来是完整的文件,但是在系统中没有名字-一个inode但是不对应文件名。这个数据仍然占用硬盘空间,但是并不能通过正常方式访问。
lost+found目录的文件通常是未链接的文件(名字已经被删除),但是这些文件还被一些进程使用(数据没有删除),在突然关机时(内核panic或者突然断电)出现。

如何恢复lost+found目录中的数据?

如果是xfs可以使用xfs_undelete,ext4的可以使用extundelete工具,testdisk适用于多种文件系统,。这里就不多讨论了,可以参考下面的文章。

如有相关问题,请在文章后面给小编留言,小编安排作者第一时间和您联系,为您答疑解惑。

extundelete参考文章:

https://blog.51cto.com/u_15127580/4030212

testdisk参考文章:

https://www.cnblogs.com/zafu/p/11406525.html

xfs_undelete参考文章:

https://blog.yufei.im/posts/%E6%81%A2%E5%A4%8Dxfs%E4%B8%AD%E8%AF%AF%E5%88%A0%E6%96%87%E4%BB%B6/

参考文章链接:

https://blog.youkuaiyun.com/ChenVast/article/details/77906712

https://www.cnblogs.com/benjamin77/p/8522021.html

https://blog.youkuaiyun.com/qq_44895681/article/details/105657604

https://blog.youkuaiyun.com/weixin_43822878/article/details/131261776

    推荐阅读   

e208079cc36ce372feb3e31c91beab35.png

f6e81d1e6a51fbdfe8ca3db886e306a9.png

    推荐视频    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值