SSDB 和 Redis 的优缺点各位哪些

SSDB 和 Redis 的优缺点各位哪些,第1张

ssdb主要看中的是和Redis兼容,这样不用改源码,就可以换个存储引擎了。

基于Redis先驱开发的存储有aerospike,vedis,ssdb,解决了多语言多线程分布式环境下快速存储问题,比mysql传统数据库要快,有的和redis协议兼容,方便更换存储引擎。

项目上需要找一个硬盘型的NoSQL,用于将 Redis 中的冷数据落入硬盘。初步选型了几款 key-value 类型的NoSQL,分别有 levelDB、 rocksDB、 TiDB、 SSDB、swapDB、 Kvrocks、Tikv 。均为基于 levelDB 开发的几款NoSQL。其中因为 levelDB、rocksDB 无网络接口,不方便做分布式和高可用。, TiDB 过重,还有 swapDB 社区不够活跃且相关client API不完备。暂时选型 SSDB 。

项目需要存储的其实是一个略长的二进制字符串,初步认为,使用 对象存储 方案其实也可以替代NoSQL,所以压测对象添加当前非常火的云原生对象存储 MinIO

硬件名|配置 系统| Ubuntu(基于win10 wsl版的docker启动) 内存| 16GB(实际可用6.08G) CPU| Intel i5-8400

测试项目: 1. 写50M数据100次 2. 随机读取任意key 100次(对LRU机制不友好)

数据导入成功!

数据序列化成功!

a 数据大小:50.99295234680176 MB

第1次写入总用时: 797 ms

第2次写入总用时: 848 ms

第3次写入总用时: 3621 ms

第4次写入总用时: 813 ms

第5次写入总用时: 1862 ms

第6次写入总用时: 838 ms

第7次写入总用时: 2235 ms

第8次写入总用时: 836 ms

第9次写入总用时: 900 ms

第10次写入总用时: 1027 ms

第11次写入总用时: 1101 ms

第12次写入总用时: 880 ms

第13次写入总用时: 1956 ms

第14次写入总用时: 866 ms

第15次写入总用时: 2422 ms

第16次写入总用时: 852 ms

第17次写入总用时: 4511 ms

第18次写入总用时: 875 ms

第19次写入总用时: 2736 ms

第20次写入总用时: 814 ms

第21次写入总用时: 7172 ms

第22次写入总用时: 891 ms

第23次写入总用时: 7820 ms

第24次写入总用时: 836 ms

第25次写入总用时: 22103 ms

第26次写入总用时: 877 ms

第27次写入总用时: 2712 ms

第28次写入总用时: 841 ms

第29次写入总用时: 1928 ms

第30次写入总用时: 916 ms

第31次写入总用时: 839 ms

第32次写入总用时: 826 ms

第33次写入总用时: 7759 ms

第34次写入总用时: 843 ms

第35次写入总用时: 10670 ms

第36次写入总用时: 843 ms

第37次写入总用时: 9361 ms

第38次写入总用时: 821 ms

第39次写入总用时: 810 ms

第40次写入总用时: 794 ms

第41次写入总用时: 13281 ms

第42次写入总用时: 833 ms

第43次写入总用时: 811 ms

第44次写入总用时: 798 ms

第45次写入总用时: 18843 ms

第46次写入总用时: 911 ms

第47次写入总用时: 9428 ms

第48次写入总用时: 898 ms

第49次写入总用时: 17582 ms

第50次写入总用时: 903 ms

第51次写入总用时: 831 ms

第52次写入总用时: 800 ms

第53次写入总用时: 14602 ms

第54次写入总用时: 827 ms

第55次写入总用时: 5898 ms

第56次写入总用时: 856 ms

第57次写入总用时: 5693 ms

第58次写入总用时: 1050 ms

第59次写入总用时: 882 ms

第60次写入总用时: 1020 ms

第61次写入总用时: 15060 ms

第62次写入总用时: 902 ms

第63次写入总用时: 1062 ms

第64次写入总用时: 915 ms

第65次写入总用时: 7572 ms

第66次写入总用时: 823 ms

第67次写入总用时: 9649 ms

第68次写入总用时: 832 ms

第69次写入总用时: 10403 ms

第70次写入总用时: 907 ms

第71次写入总用时: 978 ms

第72次写入总用时: 789 ms

第73次写入总用时: 2111 ms

第74次写入总用时: 947 ms

第75次写入总用时: 4675 ms

第76次写入总用时: 944 ms

第77次写入总用时: 8592 ms

第78次写入总用时: 832 ms

第79次写入总用时: 2940 ms

第80次写入总用时: 842 ms

第81次写入总用时: 19835 ms

第82次写入总用时: 862 ms

第83次写入总用时: 7646 ms

第84次写入总用时: 873 ms

第85次写入总用时: 1002 ms

第86次写入总用时: 842 ms

第87次写入总用时: 9057 ms

第88次写入总用时: 801 ms

第89次写入总用时: 5117 ms

第90次写入总用时: 918 ms

第91次写入总用时: 798 ms

第92次写入总用时: 853 ms

第93次写入总用时: 7728 ms

第94次写入总用时: 810 ms

第95次写入总用时: 3969 ms

第96次写入总用时: 814 ms

第97次写入总用时: 2050 ms

第98次写入总用时: 819 ms

第99次写入总用时: 9566 ms

第100次写入总用时: 833 ms</pre>

随机读

第1次读取 15总用时: 2251 ms

第2次读取 73总用时: 2045 ms

第3次读取 98总用时: 1548 ms

第4次读取 20总用时: 2683 ms

第5次读取 46总用时: 1156 ms

第6次读取 69总用时: 1160 ms

第7次读取 46总用时: 1520 ms

第8次读取 51总用时: 1381 ms

第9次读取 48总用时: 1000 ms

第10次读取 69总用时: 1400 ms

第11次读取 82总用时: 1236 ms

第12次读取 22总用时: 1140 ms

第13次读取 36总用时: 864 ms

第14次读取 66总用时: 843 ms

第15次读取 47总用时: 922 ms

第16次读取 17总用时: 885 ms

第17次读取 14总用时: 864 ms

第18次读取 64总用时: 888 ms

第19次读取 74总用时: 815 ms

第20次读取 33总用时: 866 ms

第21次读取 36总用时: 822 ms

第22次读取 78总用时: 975 ms

第23次读取 40总用时: 1186 ms

第24次读取 54总用时: 857 ms

第25次读取 92总用时: 963 ms

第26次读取 43总用时: 955 ms

第27次读取 38总用时: 853 ms

第28次读取 47总用时: 926 ms

第29次读取 62总用时: 877 ms

第30次读取 70总用时: 890 ms

第31次读取 88总用时: 895 ms

第32次读取 15总用时: 937 ms

第33次读取 3总用时: 993 ms

第34次读取 99总用时: 892 ms

第35次读取 76总用时: 818 ms

第36次读取 30总用时: 1020 ms

第37次读取 89总用时: 863 ms

第38次读取 99总用时: 819 ms

第39次读取 62总用时: 818 ms

第40次读取 1总用时: 871 ms

第41次读取 66总用时: 809 ms

第42次读取 68总用时: 847 ms

第43次读取 72总用时: 910 ms

第44次读取 50总用时: 1128 ms

第45次读取 47总用时: 898 ms

第46次读取 26总用时: 909 ms

第47次读取 35总用时: 872 ms

第48次读取 30总用时: 826 ms

第49次读取 79总用时: 904 ms

第50次读取 66总用时: 863 ms

第51次读取 2总用时: 885 ms

第52次读取 65总用时: 900 ms

第53次读取 67总用时: 1023 ms

第54次读取 16总用时: 934 ms

第55次读取 63总用时: 892 ms

第56次读取 9总用时: 894 ms

第57次读取 71总用时: 896 ms

第58次读取 20总用时: 947 ms

第59次读取 89总用时: 865 ms

第60次读取 57总用时: 872 ms

第61次读取 62总用时: 856 ms

第62次读取 14总用时: 881 ms

第63次读取 19总用时: 950 ms

第64次读取 14总用时: 876 ms

第65次读取 86总用时: 968 ms

第66次读取 12总用时: 911 ms

第67次读取 93总用时: 877 ms

第68次读取 59总用时: 886 ms

第69次读取 79总用时: 878 ms

第70次读取 49总用时: 869 ms

第71次读取 91总用时: 964 ms

第72次读取 38总用时: 838 ms

第73次读取 73总用时: 915 ms

第74次读取 8总用时: 875 ms

第75次读取 96总用时: 827 ms

第76次读取 98总用时: 826 ms

第77次读取 95总用时: 892 ms

第78次读取 36总用时: 843 ms

第79次读取 44总用时: 872 ms

第80次读取 89总用时: 863 ms

第81次读取 24总用时: 883 ms

第82次读取 89总用时: 804 ms

第83次读取 49总用时: 876 ms

第84次读取 81总用时: 873 ms

第85次读取 72总用时: 914 ms

第86次读取 68总用时: 861 ms

第87次读取 73总用时: 893 ms

第88次读取 4总用时: 880 ms

第89次读取 3总用时: 987 ms

第90次读取 76总用时: 896 ms

第91次读取 16总用时: 1010 ms

第92次读取 73总用时: 903 ms

第93次读取 83总用时: 933 ms

第94次读取 52总用时: 945 ms

第95次读取 48总用时: 901 ms

第96次读取 26总用时: 942 ms

第97次读取 37总用时: 883 ms

第98次读取 44总用时: 866 ms

第99次读取 89总用时: 921 ms

第100次读取 61总用时: 896 ms</pre>

数据导入成功!

第1次写入总用时: 956 ms

第2次写入总用时: 912 ms

第3次写入总用时: 1241 ms

第4次写入总用时: 1564 ms

第5次写入总用时: 942 ms

第6次写入总用时: 3666 ms

第7次写入总用时: 1629 ms

第8次写入总用时: 1712 ms

第9次写入总用时: 977 ms

第10次写入总用时: 1515 ms

第11次写入总用时: 911 ms

第12次写入总用时: 1009 ms

第13次写入总用时: 1024 ms

第14次写入总用时: 1206 ms

第15次写入总用时: 984 ms

第16次写入总用时: 943 ms

第17次写入总用时: 954 ms

第18次写入总用时: 1033 ms

第19次写入总用时: 1008 ms

第20次写入总用时: 1121 ms

第21次写入总用时: 963 ms

第22次写入总用时: 949 ms

第23次写入总用时: 889 ms

第24次写入总用时: 1066 ms

第25次写入总用时: 1289 ms

第26次写入总用时: 1125 ms

第27次写入总用时: 1111 ms

第28次写入总用时: 953 ms

第29次写入总用时: 964 ms

第30次写入总用时: 1125 ms

第31次写入总用时: 998 ms

第32次写入总用时: 1993 ms

第33次写入总用时: 926 ms

第34次写入总用时: 920 ms

第35次写入总用时: 926 ms

第36次写入总用时: 1169 ms

第37次写入总用时: 1325 ms

第38次写入总用时: 1170 ms

第39次写入总用时: 1074 ms

第40次写入总用时: 1011 ms

第41次写入总用时: 931 ms

第42次写入总用时: 984 ms

第43次写入总用时: 1563 ms

第44次写入总用时: 905 ms

第45次写入总用时: 944 ms

第46次写入总用时: 1147 ms

第47次写入总用时: 1429 ms

第48次写入总用时: 934 ms

第49次写入总用时: 1133 ms

第50次写入总用时: 912 ms

第51次写入总用时: 953 ms

第52次写入总用时: 1127 ms

第53次写入总用时: 1065 ms

第54次写入总用时: 1323 ms

第55次写入总用时: 1003 ms

第56次写入总用时: 1489 ms

第57次写入总用时: 1377 ms

第58次写入总用时: 940 ms

第59次写入总用时: 1317 ms

第60次写入总用时: 912 ms

第61次写入总用时: 898 ms

第62次写入总用时: 934 ms

第63次写入总用时: 1005 ms

第64次写入总用时: 1729 ms

第65次写入总用时: 983 ms

第66次写入总用时: 1684 ms

第67次写入总用时: 908 ms

第68次写入总用时: 895 ms

第69次写入总用时: 1171 ms

第70次写入总用时: 1372 ms

第71次写入总用时: 1261 ms

第72次写入总用时: 1024 ms

第73次写入总用时: 1048 ms

第74次写入总用时: 904 ms

第75次写入总用时: 941 ms

第76次写入总用时: 928 ms

第77次写入总用时: 1806 ms

第78次写入总用时: 1052 ms

第79次写入总用时: 1030 ms

第80次写入总用时: 1092 ms

第81次写入总用时: 1117 ms

第82次写入总用时: 950 ms

第83次写入总用时: 933 ms

第84次写入总用时: 928 ms

第85次写入总用时: 935 ms

第86次写入总用时: 1908 ms

第87次写入总用时: 994 ms

第88次写入总用时: 1097 ms

第89次写入总用时: 930 ms

第90次写入总用时: 1052 ms

第91次写入总用时: 1119 ms

第92次写入总用时: 958 ms

第93次写入总用时: 987 ms

第94次写入总用时: 973 ms

第95次写入总用时: 2036 ms

第96次写入总用时: 891 ms

第97次写入总用时: 954 ms

第98次写入总用时: 951 ms

第99次写入总用时: 1044 ms

第100次写入总用时: 1366 ms</pre>

随机读

第1次读取 46总用时: 40 ms

第2次读取 8总用时: 36 ms

第3次读取 28总用时: 26 ms

第4次读取 80总用时: 10 ms

第5次读取 77总用时: 13 ms

第6次读取 27总用时: 49 ms

第7次读取 86总用时: 20 ms

第8次读取 0总用时: 45 ms

第9次读取 54总用时: 34 ms

第10次读取 24总用时: 153 ms

第11次读取 78总用时: 29 ms

第12次读取 0总用时: 17 ms

第13次读取 91总用时: 56 ms

第14次读取 5总用时: 99 ms

第15次读取 23总用时: 138 ms

第16次读取 37总用时: 120 ms

第17次读取 40总用时: 156 ms

第18次读取 88总用时: 41 ms

第19次读取 76总用时: 32 ms

第20次读取 49总用时: 102 ms

第21次读取 20总用时: 179 ms

第22次读取 40总用时: 68 ms

第23次读取 6总用时: 215 ms

第24次读取 36总用时: 197 ms

第25次读取 37总用时: 30 ms

第26次读取 68总用时: 154 ms

第27次读取 14总用时: 314 ms

第28次读取 27总用时: 91 ms

第29次读取 51总用时: 255 ms

第30次读取 66总用时: 166 ms

第31次读取 86总用时: 140 ms

第32次读取 29总用时: 374 ms

第33次读取 96总用时: 235 ms

第34次读取 68总用时: 72 ms

第35次读取 74总用时: 264 ms

第36次读取 11总用时: 334 ms

第37次读取 55总用时: 316 ms

第38次读取 31总用时: 287 ms

第39次读取 93总用时: 233 ms

第40次读取 44总用时: 499 ms

第41次读取 26总用时: 312 ms

第42次读取 76总用时: 33 ms

第43次读取 11总用时: 31 ms

第44次读取 86总用时: 191 ms

第45次读取 96总用时: 217 ms

第46次读取 20总用时: 145 ms

第47次读取 1总用时: 772 ms

第48次读取 69总用时: 477 ms

第49次读取 9总用时: 320 ms

第50次读取 46总用时: 42 ms

第51次读取 34总用时: 823 ms

第52次读取 76总用时: 115 ms

第53次读取 62总用时: 635 ms

第54次读取 99总用时: 596 ms

第55次读取 64总用时: 657 ms

第56次读取 66总用时: 97 ms

第57次读取 18总用时: 461 ms

第58次读取 91总用时: 247 ms

第59次读取 46总用时: 147 ms

第60次读取 12总用时: 702 ms

第61次读取 79总用时: 545 ms

第62次读取 47总用时: 956 ms

第63次读取 17总用时: 853 ms

第64次读取 97总用时: 771 ms

第65次读取 74总用时: 368 ms

第66次读取 84总用时: 790 ms

第67次读取 72总用时: 866 ms

第68次读取 82总用时: 742 ms

第69次读取 93总用时: 313 ms

第70次读取 57总用时: 917 ms

第71次读取 61总用时: 1185 ms

第72次读取 66总用时: 162 ms

第73次读取 5总用时: 168 ms

第74次读取 68总用时: 275 ms

第75次读取 43总用时: 1108 ms

第76次读取 74总用时: 281 ms

第77次读取 65总用时: 955 ms

第78次读取 22总用时: 1169 ms

第79次读取 88总用时: 501 ms

第80次读取 80总用时: 1685 ms

第81次读取 92总用时: 1286 ms

第82次读取 89总用时: 1680 ms

第83次读取 30总用时: 1537 ms

第84次读取 41总用时: 1576 ms

第85次读取 2总用时: 2193 ms

第86次读取 52总用时: 1817 ms

第87次读取 8总用时: 323 ms

第88次读取 81总用时: 1409 ms

第89次读取 40总用时: 577 ms

第90次读取 88总用时: 598 ms

第91次读取 19总用时: 2324 ms

第92次读取 75总用时: 2275 ms

第93次读取 29总用时: 668 ms

第94次读取 77总用时: 2773 ms

第95次读取 62总用时: 484 ms

第96次读取 84总用时: 883 ms

第97次读取 32总用时: 2945 ms

第98次读取 44总用时: 884 ms

第99次读取 66总用时: 631 ms

第100次读取 38总用时: 2739 ms</pre>

非常奇怪的是 MinIO 整体性能略优于 SSDB 但是理论上不太应该, SSDB 怎么说也是半内存半硬盘的NoSQL不应该比纯硬盘的 MinIO 性能要差,有可能是 SSDB 写到一定数据量后把本机内存写爆了,导致读写非常慢。但这变相验证了 SSDB 在极端情况下的不稳定。

通常大家都会使用redis作为应用的任务队列表,redis的List结构,在一段进行任务的插入,在另一端进行任务的提取。

任务的插入

$redis->lPush("key:task:list",$task)

任务的提取

$tasks = $redis->RPop("key:task:list",0,-1)

可是大家想,如何使用mysql来实现一个队列表呢?

映入大家脑海的一个典型的模式是一个表包含多种类型的记录:未处理记录,已处理记录,正在处理记录等。一个或者多个消费者线程在表中查询未处理的记录,然后声称正在处理这个任务,处理完成之后,再讲记录更新为已处理状态。

这个典型的模式,存在两个问题;1:随着队列表越来越大,查找未处理记录的速度会越来越慢。2:频繁的加锁会让多个消费者线程增加竞争。

首先我们来创建一个表

create table unsent_emails{id int not null primary key auto_increment,status enum("unsent","claimed","sent"),

owner int unsigned not null default 0,

ts timestamp,key (owner,status,ts)

}

该表的列owner用来存储当前正在处理这个记录的连接id,由函数 CONNECTION_ID()返回的连接id或者线程id。如果这个记录当前被没有被处理,则该值为0

我们在 owner status ts上面做了索引的处理,所以查找未处理的记录会很快。

通过我们会采用 select for update的方式来标记待处理的记录,方法如下

beginselect id from unsent_emailswhere owner = 0 and status = 'unsent'

limit 10 for update-- result 10,20,33update unsent_emailsset status = 'claimed',owner = CONNECTION_ID()where id in (10,20,33)

commit

select的时候,使用了两个索引,应该会很快。问题出在select 和 update两个查询之间的间隙,这里的加锁会让其他相同的查询全部阻塞。

如果我们采用update then select的方式,那么效果就会更加高效,代码如下

set autocommit=1commitupdate unsent_emailsset statue = 'claimed',owner = CONNECTION_ID()where owner = 0 and status = 'unsent'

limit 10set autocommit=0select id from unsent_emailswhere owner = CONNECTION_ID() and status = 'claimed'

根本无需使用select去查找哪些记录还没有处理。客户端协议会告诉你更新了几条记录,就可以知道这次需要处理多少条记录。

这样是不是解决了上面的第二个问题,select for update的模式的加锁会增加多个消费队列的竞争问题。

其实所有的select for update 都可以替换为 update then select模式。

问题还没有结束,还有一种情况需要处理,就是比如正在处理任务的进程异常退出了,那么对应的进程正在处理的任务也就变为僵尸任务了。如何避免这种情况的发生呢?

所以我们还是需要一个新的定时器或者线程来定时检测并且update,将那些僵尸任务的记录更新到原始状态,就可以了。

僵尸任务的定义必须符合两点,1:任务被搁置了很久,比如十分钟,而通常一个任务只需要10秒就可以处理完;2:任务的owner(线程id或者连接id)已经不存在,只需要执行show processlist就可以获取当前正在工作的线程id了。代码如下

update unsent_emailsset owner = 0,status = 'unsent'

where owner not in (10,20,33,44) and status = 'claimed'

and ts <current_timestamp - interval 10 minute

一个基于mysql构建的队列表就完成了。

当然,最好的办法就是将任务队列从数据库中迁移出来。redis真是一个很好的队列容器,当然也可以使用ssdb(基于leveldb,内存占用更少)。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5903790.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-07
下一篇 2023-03-07

发表评论

登录后才能评论

评论列表(0条)

保存