当前位置: 首页 > news >正文

Ceph入门到精通-ceph对于长文件名如何处理

RADOS object with short name

上一篇博文,我们将介绍了对象相关的数据结构ghobject_t,以及对象在底层文件系统存储的文件名,以及如何从文件名对应到 ghobject_t对象。

映射关系如下图所示:

这里面有一个漏洞,即object name的长度,如果object name长度太长,超过了本地文件系统所能支持的最长长度怎么办?

cephfs

对于cephfs而言,对象的名字是这样的:

root@185node:/var/share/ezfs/shareroot/bean_nas# dd if=/dev/zero of=bean bs=1M count=8 
8+0 records in
8+0 records out
8388608 bytes (8.4 MB) copied, 0.00768172 s, 1.1 GB/s
root@185node:/var/share/ezfs/shareroot/bean_nas# cephfs bean map
WARNING: This tool is deprecated.  Use the layout.* xattrs to query and modify layouts.FILE OFFSET                    OBJECT        OFFSET        LENGTH  OSD0      10000000022.00000000             0       4194304  04194304      10000000022.00000001             0       4194304  1

对于cephfs中某个文件的对象是有两个部分组成的:inode 和 文件内object index, 10000000022是文件的inode,而小数点后的数字,表明的对象是文件中的第几个对象。

root@185node:/var/share/ezfs/shareroot/bean_nas# ll -li
total 8192
1099511627809 drwxrwxrwx 1 root root       1 May 29 11:39 ./
1099511627776 drwxrwxrwx 1 root root       2 May 29 11:01 ../
1099511627810 -rw-r--r-- 1 root root 8388608 May 29 11:39 bean
root@185node:/var/share/ezfs/shareroot/bean_nas# printf "%x\n" 1099511627810 
10000000022
root@185node:/var/share/ezfs/shareroot/bean_nas#

对于这种情况下,objectname是很规整的,长度是有限的,我们去底层查看对象在底层文件系统的文件:

注解:bean是pool的名字,下同root@185node:/var/log# ceph osd map bean 10000000022.00000001 
osdmap e44 pool 'bean' (15) object '10000000022.00000001' -> pg 15.b5ce59c5 (15.1c5) -> up ([1], p1) acting ([1], p1)root@185node:/data/osd.1/current/15.1c5_head# ll
total 4240
drwxr-xr-x    2 root root    4096 May 29 11:39 ./
drwxr-xr-x 3983 root root  135168 May 29 10:18 ../
-rw-r--r--    1 root root 4194304 May 29 11:39 10000000022.00000001__head_B5CE59C5__f
-rw-r--r--    1 root root       0 May 29 10:18 __head_000001C5__f

不出我们预料,对象在底层文件系统的文件名一上来就是对象的名字:10000000022.00000001

RBD

rbd的情况也类似,我们不妨创建一个rbd:

root@185node:/# rbd create -p bean  --image-format=2 --size 100 rbd_test 
root@185node:/# rbd -p bean ls
rbd_test
root@185node:/# rbd -p bean info rbd_test
rbd image 'rbd_test':size 102400 kB in 25 objectsorder 22 (4096 kB objects)used objects: 0block_name_prefix: rbd_data.6n2q5cs0j0o53format: 2features: layering
root@185node:/# 
root@185node:/# rbd -p bean map rbd_test
/dev/rbd0

注意block_name_prefix的前缀,是rbd 内对象的前缀,我们从bean 这个pool中可以找到 rbd_data.6n2q5cs0j0o53.0000000000000000 这个objcet name,总体来讲,对象名也很规整,长度有限。

我们深入到底层文件系统,找到给对象的本地文件名,也是以object name 作为文件名的起始部分:rbd\udata.6n2q5cs0j0o53.0000000000000000

root@185node:/# ceph osd map bean rbd_data.6n2q5cs0j0o53.0000000000000000 
osdmap e44 pool 'bean' (15) object 'rbd_data.6n2q5cs0j0o53.0000000000000000' -> pg 15.715f761a (15.21a) -> up ([1], p1) acting ([1], p1)root@185node:/data/osd.1/current/15.21a_head# ll
total 148
drwxr-xr-x    2 root root   4096 May 29 11:57 ./
drwxr-xr-x 3983 root root 135168 May 29 10:18 ../
-rw-r--r--    1 root root      0 May 29 10:18 __head_0000021A__f
-rw-r--r--    1 root root    513 May 29 11:57 rbd\udata.6n2q5cs0j0o53.0000000000000000__head_715F761A__f

但是RADOS object是cephfs 和 RBD的基石,RADOS是支持比较长的object name的,如下面的commit所说,RADOS是支持长达2048字节的对象名的。

commit 7e0aca18a04a3848af77f5dd2093dc2e009386ec
Author: Sage Weil <sage@redhat.com>
Date:   Wed Jul 16 14:17:27 2014 -0700osd: add config for osd_max_object_name_len = 2048 (was hard-coded at 4096)Previously we had a hard coded limit of 4096.  Objects > 3k crash the OSDwhen running on ext4, although they probably work on xfs.  But rgw onlygenerates objects a bit over 1024 bytes (maybe 1200 tops?), so let set amore reasonable limit here.  2048 is a nice round number and should besafe.Add a test.Fixes: #8174Signed-off-by: Sage Weil <sage@redhat.com>

但是很不幸,本地文件系统并没有这么强悍,支持的文件名长度都有限:

FSmax filename length in bytes
EXT4255
XFS255
ZFS255
btrfs255

这就必然带来问题,因为文件尚且不能存放下object name,更谈不上其他hash之类的字段。Ceph是如何破解这个难题的呢?

RADOS object with long name

我们不妨通过rados 命令创建一个具有超长 object name的对象:

首先我们产生一个随机的足够长的名字:

root@185node:/# xxd -l $((2048/2)) -p /dev/urandom | tr -d '\n'
acda7ad8b034a90f9b980be5ed47e242209061c2515c2021b83f1f8c49d018d621a14043a68be64ecec025a1434f040c853b7419c0c571c6b20a5e4a25fe7bf2ff181b60508622bf89f7818add55022ba17d6c9f8bd2938d97788964d0da8405a29d5fa77b07b6e4484b5335b20c9e6eb2f89bf7e805256185b580f075008815cad96f79893599b3718d0dbc05796238c2cf22cd4ee0fadc3891951bbffb0602f3b14b3af7b1efe4c96a340de12fa3ba3f4baeb166768326cfe6d79ee210228266f292bdce01eb6d5c6eb4c64ac619d1aa3853d65a614e109638bf7e04389c8b9a06b41492e65a187abc834bfd6fc4988a55c9b2ed5b91a129acf572d6661fa1cac6ce4fb181b005883b38ca600e9004244fb6ff13cde1939c54583a3dc284cd82a6f77ee171a7b7423b040fc6a65070a6ff98a8b45fd3b1de8c325e6ec00c18d077ea6442b9b134fb9d515ea51427ef8dc43bb524c0a2e6958092186e1e3ae6058b114a5d7abfd7056e55596336f9191269731b71c240e1a449b4a83094fe5d5fe2143bcb19a0f913fb4a836f317a32cf74f91b1091b1c16644b39e0ec4dbfc6ec31f9a1da6c2e6c457e976e709b68c921f630fda53185ddc5c9454a63966b5982bc0905a84f134ee7e6187b9e2cd63b4a0fb174bf626c62400517cfb6121df951b3e0e895c1c2c1bd20dc73231f91e2d692c38d2f02f91158c824104c148d08c0ac2e363d7811d964a5fa6415a477e9ac2b304b51e66c52d7ec5d3214bd5f96044a0b96fe6e29a76b2e7818a41ff50db3ebc11eade7089e03237fcb913b17c5ff6de04278ffd7754c62951e493b4044ee916dce246898724a1306c6eae97a689dc9df3f69b42aae6071b00140a8a5d09e67b732c5f093eefc7ca719a7a6d3e5f53f9a36f8a4c9a9e28d19854559f911e1b42ef66ec1a5126ee2adb1d14dc10504a6c00063babea88c1c2b6e97581f771a099388a12d1050a6fe26cba538517195ed399053bd29467422064d8f6dd0661efa9e08f432c0f8ecf42bc589fa357547dc9313da0b172514d4aa102b8a6e01f0205e3c36db2102a7788924d6d314beff379c55d9dc433520355947f4da74038b4f263d74629cac1fa1248b4a89ced59a9005b667f3923b28bb80081429baf8a2748f3f84f31213b660046c22329cf1d3de4f2636be1257c0c8de15cc945f901db2243192802c92162fffef4eee3d4f5aeb9228291d6b89df6ef7c495f9041c65e386a8d77d3ba4b6bc19f0d049d07a49ca95deac3242d0ae8f643df4c65eae119f73516da42e17f8a06b9ea17e1bf248a50b57b870be2cf2269314534a17e77fc0266e05651169a0be11328371dd426d72cb51fa7e1ab5f75f55c0db9453824eeaaa1e156b5c0e0ba27e1f2f99b0733b2b6f004f8dd9f41321b6c24d36ccda327cadc85d97132878c40bb03252cb0

其次,我们通过rados 命令,创建一个该名字的object,对象的内容是“hello world”

root@185node:/# rados --pool=bean  put acda7ad8b034a90f9b980be5ed47e242209061c2515c2021b83f1f8c49d018d621a14043a68be64ecec025a1434f040c853b7419c0c571c6b20a5e4a25fe7bf2ff181b60508622bf89f7818add55022ba17d6c9f8bd2938d97788964d0da8405a29d5fa77b07b6e4484b5335b20c9e6eb2f89bf7e805256185b580f075008815cad96f79893599b3718d0dbc05796238c2cf22cd4ee0fadc3891951bbffb0602f3b14b3af7b1efe4c96a340de12fa3ba3f4baeb166768326cfe6d79ee210228266f292bdce01eb6d5c6eb4c64ac619d1aa3853d65a614e109638bf7e04389c8b9a06b41492e65a187abc834bfd6fc4988a55c9b2ed5b91a129acf572d6661fa1cac6ce4fb181b005883b38ca600e9004244fb6ff13cde1939c54583a3dc284cd82a6f77ee171a7b7423b040fc6a65070a6ff98a8b45fd3b1de8c325e6ec00c18d077ea6442b9b134fb9d515ea51427ef8dc43bb524c0a2e6958092186e1e3ae6058b114a5d7abfd7056e55596336f9191269731b71c240e1a449b4a83094fe5d5fe2143bcb19a0f913fb4a836f317a32cf74f91b1091b1c16644b39e0ec4dbfc6ec31f9a1da6c2e6c457e976e709b68c921f630fda53185ddc5c9454a63966b5982bc0905a84f134ee7e6187b9e2cd63b4a0fb174bf626c62400517cfb6121df951b3e0e895c1c2c1bd20dc73231f91e2d692c38d2f02f91158c824104c148d08c0ac2e363d7811d964a5fa6415a477e9ac2b304b51e66c52d7ec5d3214bd5f96044a0b96fe6e29a76b2e7818a41ff50db3ebc11eade7089e03237fcb913b17c5ff6de04278ffd7754c62951e493b4044ee916dce246898724a1306c6eae97a689dc9df3f69b42aae6071b00140a8a5d09e67b732c5f093eefc7ca719a7a6d3e5f53f9a36f8a4c9a9e28d19854559f911e1b42ef66ec1a5126ee2adb1d14dc10504a6c00063babea88c1c2b6e97581f771a099388a12d1050a6fe26cba538517195ed399053bd29467422064d8f6dd0661efa9e08f432c0f8ecf42bc589fa357547dc9313da0b172514d4aa102b8a6e01f0205e3c36db2102a7788924d6d314beff379c55d9dc433520355947f4da74038b4f263d74629cac1fa1248b4a89ced59a9005b667f3923b28bb80081429baf8a2748f3f84f31213b660046c22329cf1d3de4f2636be1257c0c8de15cc945f901db2243192802c92162fffef4eee3d4f5aeb9228291d6b89df6ef7c495f9041c65e386a8d77d3ba4b6bc19f0d049d07a49ca95deac3242d0ae8f643df4c65eae119f73516da42e17f8a06b9ea17e1bf248a50b57b870be2cf2269314534a17e77fc0266e05651169a0be11328371dd426d72cb51fa7e1ab5f75f55c0db9453824eeaaa1e156b5c0e0ba27e1f2f99b0733b2b6f004f8dd9f41321b6c24d36ccda327cadc85d97132878c40bb03252cb0  <(echo "hello,world")

通过ceph osd map 命令,找到该对象的所在的OSD :

-> pg 15.5939415b (15.15b) -> up ([0], p0) acting ([0], p0)

我们去本地文件系统去寻找该对象对应的文件:

root@185node:/data/osd.0/current/15.15b_head# ll
total 152
drwxr-xr-x    2 root root   4096 May 29 10:38 ./
drwxr-xr-x 3961 root root 135168 May 29 10:18 ../
-rw-r--r--    1 root root     12 May 29 10:38 acda7ad8b034a90f9b980be5ed47e242209061c2515c2021b83f1f8c49d018d621a14043a68be64ecec025a1434f040c853b7419c0c571c6b20a5e4a25fe7bf2ff181b60508622bf89f7818add55022ba17d6c9f8bd2938d97788964d0da8405a29d5fa77b07b6e4484b5335b20c9e6eb2f_8293d87c929eba91a280_0_long
-rw-r--r--    1 root root      0 May 29 10:18 __head_0000015B__f

很明显,本地文件系统是不可能存放下长度达1K这么长的名字的,那ceph是怎么做的呢?对于长的object name,ceph是如何处理的呢?

从存储在本地文件系统的名字来看,文件名分成4个部分

  • object name prefix ,长度为FILENAME_PREFIX_LEN
  • object name 的 SHA-1 hash,注意是完整object name的SHA-1 hash
  • candidate index , 调用lfn_get_name函数时传递的参数值
  • FILENAME_COOKIE 静态字符串,就是‘long’ 这个字符串。

这四个部分通过下划线_分隔开。

这部分逻辑时在build_filename函数实现的:


void LFNIndex::build_filename(const char *old_filename, int i, char *filename, int len)
{char hash[FILENAME_HASH_LEN + 1];assert(len >= FILENAME_SHORT_LEN + 4);strncpy(filename, old_filename, FILENAME_PREFIX_LEN);filename[FILENAME_PREFIX_LEN] = '\0';if ((int)strlen(filename) < FILENAME_PREFIX_LEN)return;if (old_filename[FILENAME_PREFIX_LEN] == '\0')return;hash_filename(old_filename, hash, sizeof(hash));int ofs = FILENAME_PREFIX_LEN;while (1) {int suffix_len = sprintf(filename + ofs, "_%s_%d_%s", hash, i, FILENAME_COOKIE.c_str());if (ofs + suffix_len <= FILENAME_SHORT_LEN || !ofs)break;ofs--;}
}

这部分逻辑比较简单,如果old_filename 即原始的object name长度有限,比FILENAME_PREFIX_LEN 要短的话,那就说明时短的对象名,什么处理也不用做,直接将名字赋值给filename 即可。 但是如果old_filename 很长,就要计算名字的hash,组成长的文件名,即上面提到的4段式。


#define CEPH_CRYPTO_SHA1_DIGESTSIZE 20class LFNIndex : public CollectionIndex {/// Hash digest output size.static const int FILENAME_LFN_DIGEST_SIZE = CEPH_CRYPTO_SHA1_DIGESTSIZE;/// Length of filename hash.static const int FILENAME_HASH_LEN = FILENAME_LFN_DIGEST_SIZE;/// Max filename size.static const int FILENAME_MAX_LEN = 4096;/// Length of hashed filename.static const int FILENAME_SHORT_LEN = 255;/// Length of hashed filename prefix.static const int FILENAME_PREFIX_LEN;/// Length of hashed filename cookie.static const int FILENAME_EXTRA = 4;/// Lfn cookie value.static const string FILENAME_COOKIE;/// Name of LFN attribute for storing full name.static const string LFN_ATTR;/// Prefix for subdir index attributes.static const string PHASH_ATTR_PREFIX;/// Prefix for index subdirectories.static const string SUBDIR_PREFIX;

const int LFNIndex::FILENAME_PREFIX_LEN =  FILENAME_SHORT_LEN - FILENAME_HASH_LEN -FILENAME_COOKIE.size() -FILENAME_EXTRA;const string LFNIndex::FILENAME_COOKIE = "long";

有时候需要根据ghoject_t 来生成段的短的文件名:

string LFNIndex::lfn_get_short_name(const ghobject_t &oid, int i)
{string long_name = lfn_generate_object_name(oid);assert(lfn_must_hash(long_name));char buf[FILENAME_SHORT_LEN + 4];build_filename(long_name.c_str(), i, buf, sizeof(buf));return string(buf);
}

因为短的文件名是长的object name的摘要,必然会有数据的损失,因此,需要判断短的文件名和长的文件名是否匹配:

bool LFNIndex::short_name_matches(const char *short_name, const char *cand_long_name)
{const char *end = short_name;while (*end) ++end;const char *suffix = end;if (suffix > short_name)  --suffix;                   // last charwhile (suffix > short_name && *suffix != '_') --suffix; // back to first _if (suffix > short_name) --suffix;                   // one behind thatwhile (suffix > short_name && *suffix != '_') --suffix; // back to second _int index = -1;char buf[FILENAME_SHORT_LEN + 4];assert((end - suffix) < (int)sizeof(buf));int r = sscanf(suffix, "_%d_%s", &index, buf);if (r < 2)return false;if (strcmp(buf, FILENAME_COOKIE.c_str()) != 0)return false;build_filename(cand_long_name, index, buf, sizeof(buf));return strcmp(short_name, buf) == 0;
}

注意,刚才我提到了,SHA1本质是摘要,如果文件名从2K截断成200+字节,纵然提供了SHA1摘要,也是有数据损失的,如何根据磁盘上的文件重新获取object的所有信息呢。靠文件名肯定是不行了,有数据丢失,而且不可逆,恢复不回来object的所有信息。

ceph采用的xattr。这几天一直想先写ceph的chain_xattr, 但总觉的简单,而且机缘不到。我们先讲述原理,至于xattr,并不复杂。

root@185node:/data/osd.0/current/15.15b_head# getfattr -d acda7ad8b034a90f9b980be5ed47e242209061c2515c2021b83f1f8c49d018d621a14043a68be64ecec025a1434f040c853b7419c0c571c6b20a5e4a25fe7bf2ff181b60508622bf89f7818add55022ba17d6c9f8bd2938d97788964d0da8405a29d5fa77b07b6e4484b5335b20c9e6eb2f_8293d87c929eba91a280_0_long 
# file: acda7ad8b034a90f9b980be5ed47e242209061c2515c2021b83f1f8c49d018d621a14043a68be64ecec025a1434f040c853b7419c0c571c6b20a5e4a25fe7bf2ff181b60508622bf89f7818add55022ba17d6c9f8bd2938d97788964d0da8405a29d5fa77b07b6e4484b5335b20c9e6eb2f_8293d87c929eba91a280_0_long
user.ceph.snapset=0sAgIZAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA==
user.cephos.lfn3="acda7ad8b034a90f9b980be5ed47e242209061c2515c2021b83f1f8c49d018d621a14043a68be64ecec025a1434f040c853b7419c0c571c6b20a5e4a25fe7bf2ff181b60508622bf89f7818add55022ba17d6c9f8bd2938d97788964d0da8405a29d5fa77b07b6e4484b5335b20c9e6eb2f89bf7e805256185b580f075008815cad96f79893599b3718d0dbc05796238c2cf22cd4ee0fadc3891951bbffb0602f3b14b3af7b1efe4c96a340de12fa3ba3f4baeb166768326cfe6d79ee210228266f292bdce01eb6d5c6eb4c64ac619d1aa3853d65a614e109638bf7e04389c8b9a06b41492e65a187abc834bfd6fc4988a55c9b2ed5b91a129acf572d6661fa1cac6ce4fb181b005883b38ca600e9004244fb6ff13cde1939c54583a3dc284cd82a6f77ee171a7b7423b040fc6a65070a6ff98a8b45fd3b1de8c325e6ec00c18d077ea6442b9b134fb9d515ea51427ef8dc43bb524c0a2e6958092186e1e3ae6058b114a5d7abfd7056e55596336f9191269731b71c240e1a449b4a83094fe5d5fe2143bcb19a0f913fb4a836f317a32cf74f91b1091b1c16644b39e0ec4dbfc6ec31f9a1da6c2e6c457e976e709b68c921f630fda53185ddc5c9454a63966b5982bc0905a84f134ee7e6187b9e2cd63b4a0fb174bf626c62400517cfb6121df951b3e0e895c1c2c1bd20dc73231f91e2d692c38d2f02f91158c824104c148d08c0ac2e363d7811d964a5fa6415a477e9ac2b304b51e66c52d7ec5d3214bd5f96044a0b96fe6e29a76b2e7818a41ff50db3ebc11eade7089e03237fcb913b17c5ff6de04278ffd7754c62951e493b4044ee916dce246898724a1306c6eae97a689dc9df3f69b42aae6071b00140a8a5d09e67b732c5f093eefc7ca719a7a6d3e5f53f9a36f8a4c9a9e28d19854559f911e1b42ef66ec1a5126ee2adb1d14dc10504a6c00063babea88c1c2b6e97581f771a099388a12d1050a6fe26cba538517195ed399053bd29467422064d8f6dd0661efa9e08f432c0f8ecf42bc589fa357547dc9313da0b172514d4aa102b8a6e01f0205e3c36db2102a7788924d6d314beff379c55d9dc433520355947f4da74038b4f263d74629cac1fa1248b4a89ced59a9005b667f3923b28bb80081429baf8a2748f3f84f31213b660046c22329cf1d3de4f2636be1257c0c8de15cc945f901db2243192802c92162fffef4eee3d4f5aeb9228291d6b89df6ef7c495f9041c65e386a8d77d3ba4b6bc19f0d049d07a49ca95deac3242d0ae8f643df4c65eae119f73516da42e17f8a06b9ea17e1bf248a50b57b870be2cf2269314534a17e77fc0266e05651169a0be11328371dd426d72cb51fa7e1ab5f75f55c0db9453824eeaaa1e156b5c0e0ba27e1f2f99b0733b2b6f004f8dd9f41321b6c24d36ccda327cadc85d97132878c40bb03252cb0"
user.cephos.lfn3@1="__head_5939415B__f"
user.cephos.spill_out=0sMQA=root@185node:/data/osd.0/current/15.15b_head# 

注意该短文件名对应的文件有扩展属性信息:

  • user.cephos.lfn3
  • user.cephos.lfn3@1

ceph将object 所有需要的信息都存放在 user.cephos.lfn$INDEX_VERSION 这个扩展属性里面。 但是为什么冒出来个user.cephos.lfn3@1, 这就是chain_xattr的含义了。2个Linux 扩展属性信息存放的是一笔扩展属性,仅仅是因为EXT4这个本地文件系统扩展属性中value能存放的数据非常有限 2K,没有办法将value存放在单个key对应的 扩展属性里面,所以使用多个key来描述一个属性。这就是chain_xattr中chain的含义。

即如果你希望存放一个key value到Linux文件系统的某个文件的扩展属性中,受限于扩展属性能容纳的value长度有限,你不得不这么存放:

key key@1 key@2 key@3 

OK,都讲完了,还是有一些代码需要梳理,先到此处吧。我也累了。

相关文章:

Ceph入门到精通-ceph对于长文件名如何处理

RADOS object with short name 上一篇博文&#xff0c;我们将介绍了对象相关的数据结构ghobject_t&#xff0c;以及对象在底层文件系统存储的文件名&#xff0c;以及如何从文件名对应到 ghobject_t对象。 映射关系如下图所示&#xff1a; 这里面有一个漏洞&#xff0c;即obje…...

vue+element-ui 项目实战示例详解【目录】

vue 和 element是两个流行的前端即时&#xff0c;通常用于管理后台&#xff0c;PC等页面 能够快速构建美观的界面 1. vue2 介绍 Vue.js是一个流行的JavaScript框架&#xff0c;用于构建用户界面。它的版本分为Vue 2和Vue 3&#xff0c;而Element是一个基于Vue.js 2的UI组件库。…...

性能测试-性能调优主要方向和原则(15)

性能调优主要方向明确性能瓶颈之后,就需要进行性能调优了,调优主要从图所示的多个方向入手。能优化手段并不一定是独立应用的,在一次优化过程中很可能应用了多种优化技巧。 硬件层面优化 硬件层面优化更偏向于监控,当定位到硬件资源成为瓶颈后,更多是采用扩容等手段来解决…...

关于taos数据库使用过程中突发“unable to establish connection”问题解决

项目使用的版本信息 1.taos的版本信息 3.0.4.1 2.jdbc的版本 3.2.1 3.druid连接池版本 1.2.11问题描述 Java应用服务连接&#xff0c;突然大量抛出如下的异常信息导致应用宕机&#xff1a; sql: select server_status(), desc: unable to establish connection和集团DBA沟通…...

【Qt】Qt中将字符串转换为数字类型的函数总结以及用法示例

在Qt中&#xff0c;可以使用以下函数将字符串转换为数字类型&#xff1a; toInt()&#xff1a;将字符串转换为int类型。toDouble()&#xff1a;将字符串转换为double类型。toFloat()&#xff1a;将字符串转换为float类型。toLongLong()&#xff1a;将字符串转换为long long类型…...

效率工具3-计算机网络工具

查看各个状态的tcp连接情况 netstat -n | awk ‘/^tcp/ {S[$NF]} END {for(a in S) print a, S[a]}’ /^tcp/ 正则表达式匹配 netstat 命令输出的匹配部分&#xff0c;即以 "TCP" 开始的行{S[$NF]} 对于符合条件的每一行&#xff0c;awk 命令将使用数组 S 来计算每…...

2万多条汉字笔画笔顺查询ACCESS\EXCEL数据库

发现很多新华字典类的数据都没有笔顺的相关数据&#xff0c;因此就找了一下笔顺查询相关&#xff0c;发现有两个模式&#xff0c;一种是每个字每个笔画都有一张图片&#xff08;很庞大的图片数据量&#xff09;&#xff1b;一种是笔画图片文件显示型&#xff0c;比如今天采集的…...

我的一周年创作纪念日,感谢有你们

机缘 还记得 2022 年 09 月 19 日吗&#xff1f; 我撰写了第 1 篇技术博客&#xff1a;《纯CSS实现Material文本框&#xff08;PC和移动端都可以使用&#xff09;》&#xff1b;从此就开始了我在CSDN记录日常工作中开发和学习的第一步。在后续又参加了新星计划&#xff0c;取得…...

【音视频】ffplay源码解析-PacketQueue队列

包队列架构位置 对应结构体源码 MyAVPacketList typedef struct MyAVPacketList {AVPacket pkt; //解封装后的数据struct MyAVPacketList *next; //下一个节点int serial; //播放序列 } MyAVPacketList;PacketQueue typedef struct PacketQueue {MyAVPacketList …...

C++ 霍夫变换圆形检测

霍夫变换圆形检测 一、检测原理二、实现步骤三、算法实现一、检测原理 HoughCircles 参数说明: HoughCircles(   InputArray image,  // 输入图像 ,必须是 8 位的单通道灰度图像   OutputArray circles,  // 输出结果,发现的圆信息   Int method,  // 方法 - HOUGH…...

​南阳师范学院图书馆藏《​乡村振兴战略下传统村落文化旅游设计》许少辉八一新著——2023学生开学季辉少许

​南阳师范学院图书馆藏《​乡村振兴战略下传统村落文化旅游设计》许少辉八一新著——2023学生开学季辉少许...

如何将你在树莓派上部署的 IoT 物联网 MQTT 服务发布到公网?

​ 上一章&#xff0c;你成功的在树莓派搭建了 EMQX 开源社区版&#xff0c;用来提供 MQTT 服务&#xff0c;并验证了设备端接入和消息通信。但你发现只能在局域网内访问 emqx.local 服务&#xff0c;而 IoT 设备分布在全国各地公共网络环境&#xff0c;这些设备该如何接入呢&a…...

系统架构设计师(第二版)学习笔记----软件工程

【原文链接】系统架构设计师&#xff08;第二版&#xff09;学习笔记----软件工程 文章目录 一、软件工程1.1 软件危机的表现1.2 软件工程的内容 二、软件过程模型2.1 软件的声明周期2.2 瀑布模型2.3 瀑布模型的缺点2.4 原型模型2.5 原型模型开发阶段2.6 开发原型的途径2.7 螺旋…...

C与C++字符串分割方法示例汇总

在C语言中&#xff0c;没有内置的字符串分割函数。但是&#xff0c;你可以使用其他字符串操作函数和循环来实现字符串分割。这里是使用 strtok 函数在C中分割字符串的示例&#xff1a; #include <stdio.h> #include <string.h> int main() {char str[] "Hel…...

HTTP代理与VPN:网络代理技术的比较

HTTP代理和VPN是两种常见的网络代理技术&#xff0c;它们可以帮助用户隐藏自己的IP地址、保护网络隐私、绕过网络限制等。本文将介绍HTTP代理和VPN的定义、工作原理、优缺点以及使用场景。 一、HTTP代理 HTTP代理是一种通过代理服务器转发网络请求的技术。当用户发起网络请求时…...

免费低代码平台,助企业高效管理任务

编者按&#xff1a;本文主要介绍了免费的低代码平台实现了高效的任务管理系统&#xff0c;助力企业在任务管理方面的效率更上一层楼&#xff01;这个免费的低代码平台&#xff0c;将提高员工的工作效率。它不仅是一个任务管理系统&#xff0c;更是一个能让 企业 摆脱繁琐工作&a…...

基于conda的相关命令

conda 查看python版本环境 打开Anaconda Prompt的命令输入框 查看自己的python版本 conda env list激活相应的python版本(环境&#xff09; conda avtivate python_3.9 若输入以下命令可查看python版本 python -V #注意V是大写安装相应的包 pip install 包名5.查看已安装…...

【微信小程序】swiper的使用

1.swiper的基本使用 <jxz-header></jxz-header> <view class"banner"><swiperprevious-margin"30rpx"autoplayinterval"2000"indicator-dotsindicator-color"rgba(0,0,0,0.3)"indicator-active-color"#bda…...

iText实战--PDF和iText 简介

PDF可以做如下事务 iText 5步创建PDF import java.io.FileOutputStream; import com.itextpdf.text.Document; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.PdfWriter;public class PdfHelloWorld {/*** param args*/public static void main(String[]…...

「大数据-0.1」虚拟机VMware安装、配置、使用、创建大数据集群教程

目录 一、下载VMware Wworkstation Pro 16 二、安装VMware Wworkstation Pro 16 三、检查与设置VMware的网卡 1. 检查 2. 设置VMware网段 四、在VMware上安装Linux虚拟机 五、对安装好的虚拟机进行设置 1. 打开设置 2. 设置中文 3. 修改字体大小 4. 修改终端字体大小 5. 关闭虚…...

【HTTP】GET 和 POST 的区别

GET 和 POST 的区别 首先: GET 和 POST 没有本质区别, 具体来说, GET 的使用场景可替换为 POST,POST 使用的场景也可以替换为 GET. 语义上的区别: GET 通常用来获取数据, POST 通常用来上传数据. 现状是 GET 也经常用来上传数据, POST 也经常用来获取数据. 数据存放的位置不同…...

Unity Asset Bundle Browser 工具

Unity Asset Bundle Browser 工具 您可以在 Unity 项目中使用 Asset Bundle Browser 工具能够查看和编辑资源包的配置。 有关更多信息&#xff0c;请参阅 Unity Asset Bundle Browser 文档。 注意&#xff1a;此工具是不受支持的实用程序。查看极大的资源包可能会导致性能下…...

使用Linkerd实现流量管理:学习如何使用Linkerd的路由规则来实现流量的动态控制

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

1462. 课程表 IV

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;Floyd传递闭包方法二&#xff1a;拓扑排序 思考写在最后 Tag 【拓扑排序】【传递闭包】【并查集】【数组】 题目来源 1462. 课程表 IV 题目解读 给你一个表示课程先决条件的数组 prerequisites&#xff0c;prerequis…...

QTday2

完善登录框 点击登录按钮后&#xff0c;判断账号&#xff08;admin&#xff09;和密码&#xff08;123456&#xff09;是否一致&#xff0c;如果匹配失败&#xff0c;则弹出错误对话框&#xff0c;文本内容“账号密码不匹配&#xff0c;是否重新登录”&#xff0c;给定两个按钮…...

thrift的简单使用

写在前面 本文一起看下一种由facebook出品的rpc框架thrift。 源码 。 1&#xff1a;开发步骤 1:编写thrift idl文件 2&#xff1a;根据thrift idl文件生成java模板代码 3&#xff1a;继承模板代码的*.Iface接口给出server的具体服务实现 4&#xff1a;使用模板的HelloWorldSe…...

Python实现猎人猎物优化算法(HPO)优化随机森林分类模型(RandomForestClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 猎人猎物优化搜索算法(Hunter–prey optimizer, HPO)是由Naruei& Keynia于2022年提出的一种最新的…...

2023年7月京东平板电脑行业品牌销售排行榜(京东销售数据分析)

鲸参谋监测的京东平台7月份平板电脑市场销售数据已出炉&#xff01; 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年7月份&#xff0c;京东平台上平板电脑的销量为68万&#xff0c;同比增长超过37%&#xff1b;销售额为22亿&#xff0c;同比增长约54%。从价格上看…...

HTML显示中文空格字符,emsp;一个中文字符,ensp;半个中文字符

&emsp;一个中文字符 &ensp;半个中文字符 <ul><li class"li">姓&emsp;&emsp;名&#xff1a;<input type"text" /></li><li class"li">手&ensp;机&ensp;号&#xff1a;<input type"…...

Python基础指令(上)

Python基础指令上 常量和表达式变量和类型1. 什么是变量2. 变量的语法2.1 定义变量2.2 使用变量 3. 变量的类型4. 为什么要有这么多类型5. 动态类型特性 注释输入输出1. 程序与用户的交互2. 通过控制台输出3. 通过控制台输入 运算符1. 算术运算符2. 关系运算符3. 逻辑运算符4. …...

淮阳 网站建设/百度高级搜索引擎入口

SAM很好用的啊。。。 传送门 双倍经验&#xff1a;L-Gap Substrings 基本做法类似&#xff0c;这道题的差分改掉&#xff0c;map 改掉就好了QWQ noteskey 反正就是先差分一下&#xff0c;然后把首项丢掉&#xff08;没有比较的对象自然就不算趋势了&#xff09; 然后就是建 SAM…...

沂源放心企业网站建设方案报价/百度pc端网页版

题目在这里啊 A.最长上升子序列&#xff0c;范围很小所以写了简单的O(n^2)算法 #include <iostream>#define rep(i, j, k) for(int i j;i < k;i )#define rev(i, j, k) for(int i j;i > k;i --)using namespace std;typedef long long ll;int n, m, a[1111], f[1…...

三河市最新消息/seo技术交流论坛

拿到Nuvi 350的时候&#xff0c;我惊讶不已&#xff0c;有这么小巧的GPS&#xff1f;竟然比PDA还要小一点点。把玩了一下&#xff0c;喜欢的不得了。下面我就同大家一起来分享我的Nuvi 350试用手记。 很早就去浏览台湾的Garmin网站&#xff0c;对在台湾新上市的Nuvi 350心仪不已…...

在线python编程网页/seo咨询推广

什么是 Visual Paradigm IT项目管理框架&#xff1f; 框架是一组工具&#xff0c;可以帮助您更快&#xff0c;更好地完成工作。IT项目管理框架是一个概念&#xff0c;方法和工具的集合&#xff0c;帮助项目团队实现以下目标。 管理项目生命周期&#xff1a;从项目识别到项目启动…...

做公司做网站有用吗/培训教育

在Qt的model/view中&#xff0c;QStandardItem是可以设置复选效果的&#xff0c;在QTreeView和QTableView等中以QCheckBox的样子显示出来。 item->setCheckable(true); // 设置是否能复选&#xff08;默认只有√和两种形态&#xff09; item->setTristate(true); …...

哪些网站做简历合适/seo关键词排名公司

redis集群 java架构师项目实战,高并发集群分布式,大数据高可用,视频教程在redis3.0之前&#xff0c;出现了sentinel工具来监控各个Master的状态&#xff08;可以看上一篇博客&#xff09;。如果Master异常则会做主从切换。选举一个slave作为新的Master&#xff0c;3.0之后出现了…...