-
RAID的介绍、使用以及监控
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
RAID 0(至少需要两块盘)
RAID 0是以条带化的方式,分别向两块盘,并行地写入数据,读取时也是并行的。一方面,并行操作可以充分利用I/O总线的**带宽**,提高磁盘整体存取性能;另一方面,它有RAID级别中最高的空间利用率,但是没有数据冗余,存在单点故障。
RAID 1(至少需要2块硬盘,一般为双数)
RAID 0是以镜像的方式,分别向两块盘,并行写入相同的数据。有数据冗余,可靠性强,一半写数据,一半用来做备份,但是硬盘容量会减少一半。读取时,从两块硬盘上并行读取,写入慢,读取快。
RAID 5(需要3块以上硬盘)
RAID 5采用奇偶校验,可靠性强,磁盘校验和被散列到不同的磁盘里面,增加了读写速率。只有当两块磁盘同时丢失时,数据才无法恢复,至少三块硬盘并且硬盘大小应该相等才能组成Raid 5阵列
RAID使用
软raid
mdadm是multiple devices admin的简称,它是Linux下的一款标准的软件 RAID 管理工具
安装:
#直接用yum\apt安装即可 yum install mdadm
常用参数:
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
常见参数含义
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.csdn.net/ChenVast/article/details/77906712
https://www.cnblogs.com/benjamin77/p/8522021.html