å®éšã§ã¯ãIntel C610ãããã»ããïŒC1ã¹ãããã³ã°ãQPIã·ã¹ãã ãã¹ã9.6 GT / sïŒã«åºã¥ããµãŒããŒã䜿çšãã12ã³ã¢ã®Intel Xeon E5-2697ããã»ããµãŒãã€ã³ã¹ããŒã«ãããŠããŸãïŒã¯ããã¯åšæ³¢æ°-2.7 GHzãã¢ãŒãã§24ã®è«çã³ã¢ïŒ HTïŒã RAMæ§æ-8x8 GBïŒSamsung M393B1G73BH0 DDR3 1866ïŒã ã·ã¹ãã ã«ã¯Intel SSD DC P3700ã·ãªãŒãºããããŸãã OSãCentOS 7.2.1511ïŒã«ãŒãã«3.10.0ïŒã䜿çšããããã
LinuxãŠãŒã¶ãŒç©ºéã§å®è¡ããNVMeãã©ã€ããŒãå¿ èŠãªã®ã¯ãªãã§ããïŒ
æŽå²çã«ããã£ã¹ã¯ãã©ã€ãã¯ãRAMãããã»ããµãªã©ãã³ã³ãã¥ãŒã¿ãŒã·ã¹ãã ã®ä»ã®ã³ã³ããŒãã³ããããæ¡éãã«äœéã§ãã ã€ãŸãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãšããã»ããµã¯ãå²ã蟌ã¿ã¡ã«ããºã ã䜿çšããŠãã£ã¹ã¯ãšã®ããåãã匷å¶ãããŸãã ããšãã°ããã®çžäºäœçšã®ã»ãã·ã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
- ãã£ã¹ã¯ããããŒã¿ãèªã¿åãããã«ãOSã«èŠæ±ãè¡ãããŸãã
- ãã©ã€ããŒã¯ãã®èŠæ±ãåŠçããããŒããŠã§ã¢ãšéä¿¡ããŸãã
- ãã£ã¹ã¯ãã¬ãŒããå転ããŸãã
- èªã¿åã/æžã蟌ã¿ãããããã¬ãŒãã®ç®çã®éšåã«ç§»åããããŒã¿ã®èªã¿åããéå§ããæºåãããŸãã
- ããŒã¿ã¯ãããã¡ã«èªã¿æžããããŸãã
- ã·ã¹ãã ã§ããŒã¿ã䜿çšããæºåãã§ããããšãããã»ããµã«éç¥ããå²ã蟌ã¿ãçæãããŸãã
- ãããŠæåŸã«ãããŒã¿ããããã¡ããèªã¿åãããŸãã
å²ã蟌ã¿ã¢ãã«ã¯ãã·ã¹ãã ã«è¿œå ã®è² è·ãäœæããŸãã ãã ããéåžžããã®è² è·ã¯ãåŸæ¥ã®ããŒããã©ã€ãã«å žåçãªé 延ãããå€§å¹ ã«å°ãããªããŸããã ãã®çµæãããŒã¿ã¹ãã¬ãŒãžãµãã·ã¹ãã ã®å¹çãå€§å¹ ã«äœäžãããããšãã§ããªãã£ãããããã®è¿œå ã®è² è·ã¯ããŸã泚ç®ãããŸããã§ããã
æè¿ãSSDãš3D XPointã¹ãã¬ãŒãžãªã©ã®æ¬¡äžä»£ãã¯ãããžãŒã¯ãåŸæ¥ã®HDDãããå€§å¹ ã«é«éã§ãã ãã®çµæã以åã¯ããŒããŠã§ã¢ã§ãã£ãããŒã¿ã¹ãã¬ãŒãžãµãã·ã¹ãã ã®ããã«ããã¯ãããœãããŠã§ã¢ã¡ã«ããºã ã®é åã«ç§»è¡ããŸããã äžã®å³ã§ãããããã«ããã©ã€ãã®å¿çé床ãšæ¯èŒããŠããã©ã€ããšãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãæäœããããã»ã¹ã«å²ã蟌ã¿ãããããé 延ã¯éåžžã«å€§ããèŠããŸãã
3D XPointãã¯ãããžãŒã«åºã¥ãSSDãšã¹ãã¬ãŒãžã·ã¹ãã ã¯ãåŸæ¥ã®HDDãããã¯ããã«é«éã«åäœããŸãã ãã®çµæããœãããŠã§ã¢ã®ããã«ããã¯ãããã«ããã¯ã«ãªããŸããã
LinuxãŠãŒã¶ãŒç©ºéã§å®è¡ãããNVMeãã©ã€ããŒã¯ããå²ã蟌ã¿ã®åé¡ãã解決ããŸãã ã¡ãã»ãŒãžãæäœãå®äºããã®ãåŸ ã€ä»£ããã«ãèªã¿åããŸãã¯æžã蟌ã¿äžã«ã¹ãã¬ãŒãžããã€ã¹ãããŒãªã³ã°ããŸãã ããã«ãããã¯éåžžã«éèŠã§ããNVMeãã©ã€ããŒã¯ãŠãŒã¶ãŒç©ºéå ã§åäœããŸãã ããã¯ãã¢ããªã±ãŒã·ã§ã³ãLinuxã«ãŒãã«ããã€ãã¹ããŠNVMeããã€ã¹ãšçŽæ¥å¯Ÿè©±ã§ããããšãæå³ããŸãã ãã®ã¢ãããŒãã®å©ç¹ã®1ã€ã¯ãã³ã³ããã¹ãã®åãæ¿ããå¿ èŠãšããã·ã¹ãã ã³ãŒã«ãåãé€ãããšã§ãã ããã«ãããã·ã¹ãã ã«è¿œå ã®è² è·ãããããŸãã NVMeã¢ãŒããã¯ãã£ã¯ããããã³ã°ãæäŸããŸãã;ããã¯ãã¹ã¬ããéã§ããŒã¿ãåæããããã«ããã»ããµã¡ã«ããºã ã䜿çšããªãããšãç®çãšããŠããŸãã åãã¢ãããŒããI / Oã³ãã³ãã®äžŠåå®è¡ãæäŸããŸãã
SPDKã®NVMeãŠãŒã¶ãŒã¹ããŒã¹ãã©ã€ããŒãšLinuxã«ãŒãã«ã¢ãããŒããæ¯èŒãããšãNVMeãã©ã€ããŒã䜿çšãããšãã·ã¹ãã ã®äœåãªè² è·ã«ããé 延ãçŽ10åæžå°ããããšãããããŸãã
Linuxã«ãŒãã«ãšSPDKã¡ã«ããºã ã䜿çšããŠãã©ã€ããæäœãããšãã«çºçããé 延ïŒããç§åäœïŒ
SPDKã¯ã1ã€ã®ããã»ããµã³ã¢ã䜿çšããŠ8ã€ã®NVMe SSDãåŠçã§ãã350äžãè¶ ããIOPãæäŸããŸãã
Linuxã«ãŒãã«ãšSPDKã¡ã«ããºã ã䜿çšããŠç°ãªãæ°ã®SSDãæ±ãå Žåã®I / Oããã©ãŒãã³ã¹ãå€æŽãã
åææ¡ä»¶ãšSPDKãã«ã
SPDKã¯ãFedoraãCentOSãUbuntuãDebianãFreeBSDãªã©ã®OSã§ã®äœæ¥ããµããŒãããŠããŸãã SPDKã®å®è¡ã«å¿ èŠãªããã±ãŒãžã®å®å šãªãªã¹ãã¯ã ããã«ãããŸã ã
SPDKãæ§ç¯ããåã«ã DPDK ïŒData Plane Development KitïŒãã€ã³ã¹ããŒã«ããå¿ èŠããããŸããããã¯ãSPDKãDPDKã«ãã§ã«ååšããã¡ã¢ãªç®¡çãšãã¥ãŒæ©èœã«äŸåããŠããããã§ãã DPDKã¯ããããã¯ãŒã¯ãã±ããã®åŠçã«äžè¬çã«äœ¿çšãããæçããã©ã€ãã©ãªã§ãã ã¡ã¢ãªç®¡çãšããŒã¿ãã¥ãŒã®é«éåŠçã«æé©ã§ãã
SPDKã®ãœãŒã¹ã³ãŒãã¯ã次ã®ã³ãã³ãã䜿çšããŠGitHubãªããžããªããè€è£œã§ããŸãã
git clone https://github.com/spdk/spdk.git
âDPDKãã«ãïŒLinuxçšïŒ
cd /path/to/build/spdk wget http://fast.dpdk.org/rel/dpdk-16.07.tar.xz tar xf dpdk-16.07.tar.xz cd dpdk-16.07 && make install T=x86_64-native-linuxapp-gcc DESTDIR=.
âSPDKã¢ã»ã³ããªïŒLinuxçšïŒ
ã¢ã»ã³ãã«ãããDPDKãSPDKãã©ã«ããŒã«é 眮ããããããã®ãã£ã¬ã¯ããªã«æ»ã£ãŠSPDKããã«ãããDPDKã«makeãã¹ãæž¡ããŸãã
cd /path/to/build/spdk make DPDK_DIR=./dpdk-16.07/x86_64-native-linuxapp-gcc
SPSPDKã¢ããªã±ãŒã·ã§ã³ãèµ·åããåã®ã·ã¹ãã ã®æ§æ
次ã®ã³ãã³ãã䜿çšãããšãã¡ã¢ãªã®å€§ããªããŒãžïŒå·šå€§ããŒãžïŒã®äœ¿çšãæå¹ã«ããNVMeããã³I / OATããã€ã¹ãã«ãŒãã«ãã©ã€ããŒããåãé¢ãããšãã§ããŸãã
sudo scripts/setup.sh
ãµã€ãºã2 MBãªã®ã§ã倧ããªããŒãžã䜿çšããããšãããã©ãŒãã³ã¹ã«ãšã£ãŠéèŠã§ãã ããã¯ãæšæºã®4kããŒãžãã¯ããã«è¶ ããŠããŸãã ã¡ã¢ãªããŒãžã®ãµã€ãºãå¢å ããããã翻蚳å€æãããã¡ïŒTLBïŒã§ãã¹ãçºçããå¯èœæ§ãäœããªããŸãã TLBã¯ãä»®æ³ã¢ãã¬ã¹ãç©çã¡ã¢ãªã¢ãã¬ã¹ã«å€æããããã»ããµå ã®ã³ã³ããŒãã³ãã§ãã ãããã£ãŠã倧ããªããŒãžã䜿çšãããšãTLBãããå¹ççã«äœ¿çšã§ããŸãã
Hello Worldãµã³ãã«ã¢ããªã±ãŒã·ã§ã³
SPDKã«ã¯å€ãã®äŸãå«ãŸããŠãããå質ã«é¢ããããã¥ã¡ã³ãã¯ãã¡ãããå ¥æã§ããŸãã ããã«ãããããã«éå§ã§ããŸãã ãHello Worldããšãããã¬ãŒãºãæåã«NVMeããã€ã¹ã«ä¿åããã次ã«ãããã¡ã«èªã¿æ»ãããäŸãèããŸãã
ã³ãŒãã«å ¥ãåã«ãNVMeããã€ã¹ã®æ§é ã«ã€ããŠèª¬æããNVMeãã©ã€ããŒããã®æ å ±ã䜿çšããŠããã€ã¹ãæ€åºããããŒã¿ãæžã蟌ãã§ããèªã¿åãæ¹æ³ã®äŸã玹ä»ãã䟡å€ããããŸãã
NVMeããã€ã¹ïŒNVMeã³ã³ãããŒã©ãŒãšãåŒã°ããŸãïŒã¯ã次ã®èæ ®äºé ã«åºã¥ããŠæ§æãããŠããŸãã
- ã·ã¹ãã ã«ã¯ã1ã€ä»¥äžã®NVMeããã€ã¹ããããŸãã
- åNVMeããã€ã¹ã¯ãããã€ãã®ããŒã ã¹ããŒã¹ã§æ§æãããŸãïŒãã®å Žåã¯1ã€ã ãã§ãïŒã
- åããŒã ã¹ããŒã¹ã¯ãå€æ°ã®è«çãããã¯ã¢ãã¬ã¹ïŒLBAïŒã§æ§æãããŠããŸãã
ããã§ã¯ãã¹ããããã€ã¹ãããã®äŸãèŠãŠã¿ãŸãããã
ã»ããã¢ãã
- ç°å¢æœè±¡åã¬ã€ã€ãŒDPDKïŒEnvironment Abstraction LayerãEALïŒãåæåããŸãã 以äžã®ã³ãŒãã§ã¯ã
-c
ã¯ã³ãŒããå®è¡ãããã«ãŒãã«ãéžæããããã®ããããã¹ã¯ã§ããân
ã¯ã«ãŒãã«IDã--proc-type
ã¯hugetlbfsãã¡ã€ã«ã·ã¹ãã ãããŠã³ãããããã£ã¬ã¯ããªã§ãã
static char *ealargs[] = { "hello_world", "-c 0x1", "-n 4", "--proc-type=auto", }; rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs);
- èŠæ±ãããã¡ãŒã®ããŒã«ãäœæããŠã¿ãŸããããããã¯ãåI / OèŠæ±ã®ããŒã¿ãæ ŒçŽããããã«SPDKå
ã§äœ¿çšãããŸãã
request_mempool = rte_mempool_create("nvme_request", 8192, spdk_nvme_request_size(), 128, 0, NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
- NVMeããã€ã¹ã®ååšã«ã€ããŠã·ã¹ãã ããã§ãã¯ããŸãããã
rc = spdk_nvme_probe(NULL, probe_cb, attach_cb, NULL);
- NVMeããã€ã¹ãåæããããã€ã¹ãæ¥ç¶ããå¿
èŠããããã©ããã瀺ãè«çå€ãSPDKã«è¿ããŸãã
static bool probe_cb(void *cb_ctx, struct spdk_pci_device *dev, struct spdk_nvme_ctrlr_opts *opts) { printf("Attaching to %04x:%02x:%02x.%02x\n", spdk_pci_device_get_domain(dev), spdk_pci_device_get_bus(dev), spdk_pci_device_get_dev(dev), spdk_pci_device_get_func(dev)); return true; }
- ããã€ã¹ãæ¥ç¶ãããŠããŸãã ããã§ãããŒã ã¹ããŒã¹ã®æ°ã«é¢ããããŒã¿ããªã¯ãšã¹ãã§ããŸãã
static void attach_cb(void *cb_ctx, struct spdk_pci_device *dev, struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts) { int nsid, num_ns; const struct spdk_nvme_ctrlr_data *cdata = spdk_nvme_ctrlr_get_data(ctrlr); printf("Attached to %04x:%02x:%02x.%02x\n", spdk_pci_device_get_domain(dev), spdk_pci_device_get_bus(dev), spdk_pci_device_get_dev(dev), spdk_pci_device_get_func(dev)); snprintf(entry->name, sizeof(entry->name), "%-20.20s (%-20.20s)", cdata->mn, cdata->sn); num_ns = spdk_nvme_ctrlr_get_num_ns(ctrlr); printf("Using controller %s with %d namespaces.\n", entry->name, num_ns); for (nsid = 1; nsid <= num_ns; nsid++) { register_ns(ctrlr, spdk_nvme_ctrlr_get_ns(ctrlr, nsid)); } }
- ãµã€ãºãªã©ã®æ
å ±ãååŸããããã«ãåå空éãåæããŸãã
static void register_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns) { printf(" Namespace ID: %d size: %juGB\n", spdk_nvme_ns_get_id(ns), spdk_nvme_ns_get_size(ns) / 1000000000); }
- åå空éã«èªã¿åã/æžã蟌ã¿èŠæ±ãéä¿¡ããããã®å
¥åãã¥ãŒã®ãã¢ïŒãã¥ãŒãã¢ïŒãäœæããŸãããã
ns_entry->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ns_entry->ctrlr, 0);
dataããŒã¿ã®èªã¿åã/æžã蟌ã¿
- èªã¿æžãããããŒã¿çšã®ãããã¡ãå²ãåœãŠãŸãã
sequence.buf = rte_zmalloc(NULL, 0x1000, 0x1000);
- æååãHello Worldããã¯ãªããããŒãã«ã³ããŒããŸãã
sprintf(sequence.buf, "Hello world!\n");
- ããã€ãã®ãã¥ãŒããããã¡ãŒãžã®ãã€ã³ã¿ãŒãLBAã€ã³ããã¯ã¹ãããŒã¿ã®æžã蟌ã¿åŸã«æ©èœããã³ãŒã«ããã¯é¢æ°ãããã³ã³ãŒã«ããã¯é¢æ°ã«æž¡ãå¿
èŠãããããŒã¿ãžã®ãã€ã³ã¿ãŒãæäŸããããšã«ãããæå®ãããåå空éã«æžã蟌ã¿èŠæ±ãéä¿¡ããŸãã
rc = spdk_nvme_ns_cmd_write(ns_entry->ns, ns_entry->qpair, sequence.buf, 0, /* LBA */ 1, /* */ write_complete, &sequence, 0);
- èšé²ããã»ã¹ãå®äºãããšãã³ãŒã«ããã¯é¢æ°ãåæçã«åŒã³åºãããŸãã
- æå®ãããããŒã ã¹ããŒã¹ã«èªã¿åãèŠæ±ãéä¿¡ããæžã蟌ã¿èŠæ±ã«äœ¿çšãããã®ãšåããµãŒãã¹ããŒã¿ã®ã»ãããæäŸããŸãã
rc = spdk_nvme_ns_cmd_read(ns_entry->ns, ns_entry->qpair, sequence->buf, 0, /* LBA start */ 1, /* number of LBAs */ read_complete, (void *)sequence, 0);
- èªã¿åãããã»ã¹ãå®äºãããšãã³ãŒã«ããã¯é¢æ°ãåæçã«åŒã³åºãããŸãã
- èªã¿åãããã³æžã蟌ã¿æäœã®å®äºã瀺ããã©ã°ã確èªããŸãã ãªã¯ãšã¹ãããŸã åŠçãããŠããå Žåãæå®ããããã¥ãŒã®ãã¢ã®ã¹ããŒã¿ã¹ã確èªã§ããŸãã å®éã®ããŒã¿ã®èªã¿åãããã³æžã蟌ã¿æäœã¯éåæã«å®è¡ãããŸããã
spdk_nvme_qpair_process_completions
é¢æ°ã¯é²è¡ç¶æ³ã確èªããå®äºããI / OèŠæ±ã®æ°ãè¿ããŸãããŸããäžèšã®èªã¿åãããã³æžã蟌ã¿æé ã®å®äºãéç¥ããã³ãŒã«ããã¯é¢æ°ãåŒã³åºããŸãã
while (!sequence.is_completed) { spdk_nvme_qpair_process_completions(ns_entry->qpair, 0); }
- çµäºããåã«ãããã€ãã®ãã¥ãŒããã®ä»ã®ãªãœãŒã¹ã解æŸããŸãã
spdk_nvme_ctrlr_free_io_qpair(ns_entry->qpair);
GitHubã«æçš¿ããããããã§è§£æãããäŸã®å®å šãªã³ãŒãã次ã«ç€ºããŸãã SPDK NVMe API ããã¥ã¡ã³ã㯠ãspdk.ioã«ãããŸãã
ãHello Worldããéå§ãããšã次ã衚瀺ãããŸãã
Hello Worldã®äŸã®çµæ
SPDKã«å«ãŸãããã®ä»ã®äŸ
SPDKã«ã¯ãããã°ã©ããŒãSPDKãã©ã®ããã«æ©èœããããè¿ éã«ææ¡ããç¬èªã®ãããžã§ã¯ãã®éçºãéå§ã§ããããã«èšèšãããå€ãã®äŸãå«ãŸããŠããŸãã
ããã§ãããšãã°ãNVMeãã£ã¹ã¯ã®ããã©ãŒãã³ã¹ããã¹ãããperfã®äŸã®çµæã
NVMeãã£ã¹ã¯ã®ããã©ãŒãã³ã¹ããã¹ãããããã©ãŒãã³ã¹ã®äŸ
æ©èœã管çåœä»€ã»ããã®å±æ§ãNVMeåœä»€ã»ããã®å±æ§ãé»æºç®¡çæ å ±ãããã€ã¹ã®æè¡ç¶æ ã«é¢ããæ å ±ãªã©ãNVMeãã£ã¹ã¯ã«é¢ããæ å ±ã«ã¢ã¯ã»ã¹ããå¿ èŠãããéçºè ã¯ã èå¥äŸã䜿çšã§ããŸãã
NVMeãã©ã€ãã«é¢ããæ å ±ã衚瀺ããäŸãç¹å®ãã
çµè«
LinuxãŠãŒã¶ãŒç©ºéã§å®è¡ãããSPDKãšãã©ã€ããŒã䜿çšããŠNVMeãã£ã¹ã¯ãæäœããæ¹æ³ã«ã€ããŠèª¬æããŸããã ãã®ã¢ãããŒãã«ãããããŒã¿ã¹ãã¬ãŒãžããã€ã¹ãžã®ã¢ã¯ã»ã¹ã«ã«ãŒãã«ã¡ã«ããºã ã䜿çšããããšã§çããè¿œå ã®é 延ãæå°éã«æãããããã©ã€ããšã·ã¹ãã éã®ããŒã¿è»¢éé床ãåäžãããããšãã§ããŸãã
SPDKã䜿çšããé«æ§èœãã£ã¹ã¯ãã©ã€ãã¢ããªã±ãŒã·ã§ã³ã®éçºã«èå³ãããå Žåã¯ããã¡ãã®SPDKã¡ãŒãªã³ã°ãªã¹ãã«ç»é²ã§ããŸãã ãããŠã ãããšãã -圹ã«ç«ã€ãããªè³æã