版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
分布式存储系统:Cassandra:Cassandra的读写操作与数据一致性1分布式存储系统:Cassandra简介1.1Cassandra的历史与发展Cassandra,一个高度可扩展的分布式NoSQL数据库,最初由Facebook开发,旨在处理大规模数据的存储需求。2008年,Facebook将其开源,随后被Apache软件基金会采纳,成为顶级项目。Cassandra的设计灵感来源于Amazon的Dynamo和Google的Bigtable,它结合了两者的优势,提供了一个既能处理大量数据,又能保证高可用性和容错性的存储解决方案。1.1.1发展历程2008年:Facebook开源Cassandra。2009年:Cassandra被Apache软件基金会接纳为孵化器项目。2010年:Cassandra正式成为Apache的顶级项目。2011年至今:Cassandra社区持续壮大,版本不断更新,支持更多的功能和优化。1.2Cassandra的核心特性与优势Cassandra的核心特性使其在分布式存储领域独树一帜,尤其在数据一致性、高可用性和可扩展性方面表现突出。1.2.1数据一致性与读写操作Cassandra采用了一种称为“最终一致性”的模型,这意味着在分布式环境中,数据可能不会立即在所有节点上一致,但最终会达到一致状态。这种模型在保证高可用性的同时,也允许系统在大多数情况下提供快速的读写操作。读写一致性级别Cassandra允许用户在读写操作时指定一致性级别,这包括:ANY:只要有一个节点响应,操作就认为成功。ONE:至少有一个节点响应,操作成功。TWO:至少有两个节点响应,操作成功。THREE:至少有三个节点响应,操作成功。QUORUM:大多数节点响应,操作成功。ALL:所有节点响应,操作成功。LOCAL_QUORUM:本地数据中心的大多数节点响应,操作成功。EACH_QUORUM:每个数据中心的大多数节点响应,操作成功。示例代码fromcassandra.clusterimportCluster
#连接Cassandra集群
cluster=Cluster([''])
session=cluster.connect()
#设置一致性级别为QUORUM
session.default_consistency_level='QUORUM'
#插入数据
session.execute(
"""
INSERTINTOkeyspace.table(id,name,age)
VALUES(%s,%s,%s)
""",
(1,'JohnDoe',30)
)
#读取数据
rows=session.execute('SELECT*FROMkeyspace.tableWHEREid=%s',[1])
forrowinrows:
print(,row.age)1.2.2高可用性Cassandra通过数据复制和故障恢复机制确保高可用性。每个数据项都会在多个节点上复制,如果某个节点失败,其他节点可以继续提供服务,确保数据的持续访问。数据复制Cassandra使用虚拟节点(vNodes)和一致性哈希环来分配数据和复制数据。每个节点负责环上的一部分数据,通过调整虚拟节点的数量,可以控制数据的复制因子。1.2.3可扩展性Cassandra的设计允许它在不中断服务的情况下轻松扩展。当需要增加存储容量或提高性能时,只需向集群中添加更多节点即可。动态扩展当向Cassandra集群中添加新节点时,数据会自动重新分布,以利用新增的存储资源。这一过程对应用程序是透明的,无需修改应用程序代码。1.2.4总结Cassandra凭借其最终一致性模型、高可用性和动态可扩展性,成为处理大规模数据存储的理想选择。通过灵活的一致性级别设置,用户可以根据自己的需求平衡读写性能和数据一致性。同时,Cassandra的高可用性和可扩展性特性,确保了系统在面对大量数据和高并发访问时的稳定性和效率。2Cassandra的基本架构2.1数据模型与列族Cassandra的数据模型基于列族(ColumnFamily),这是一种类似于关系数据库中的表的结构,但更灵活。列族可以包含多个列,每个列都有一个唯一的列名。列名可以是任意字节序列,这使得Cassandra能够存储非结构化数据。列族中的列可以分为两类:静态列和动态列。静态列在创建列族时定义,而动态列则在插入数据时动态添加。2.1.1示例:创建列族和插入数据//创建一个列族
CREATEKEYSPACEexampleWITHreplication={'class':'SimpleStrategy','replication_factor':'3'};
//在example键空间中创建一个列族
CREATETABLEexample.users(
useriduuidPRIMARYKEY,
usernametext,
emailtext,
ageint
);
//插入数据
INSERTINTOexample.users(userid,username,email,age)VALUES(uuid(),'JohnDoe','john.doe@',30);在上述示例中,我们首先创建了一个名为example的键空间,然后在该键空间中创建了一个名为users的列族。列族的主键是userid,这是一个UUID类型,确保每个用户都有一个唯一的标识符。我们还定义了username、email和age列,它们分别存储用户的姓名、电子邮件和年龄。2.2分布式架构与数据分布Cassandra是一个分布式数据库,它使用一种称为“虚拟节点”的技术来在集群中分布数据。每个节点在环上拥有多个虚拟节点,这增加了数据分布的均匀性和容错性。Cassandra的数据分布是基于哈希环的,每个数据项根据其主键的哈希值被分配到环上的一个节点。为了提高数据的可用性和持久性,Cassandra使用复制策略,数据会被复制到多个节点上。2.2.1数据分布示例假设我们有一个Cassandra集群,包含三个物理节点,每个节点有三个虚拟节点。当数据被插入时,Cassandra会根据数据的主键计算其哈希值,然后将数据放置在环上的相应位置。例如,如果一个用户的userid哈希值指向节点1的虚拟节点1,那么数据将被存储在节点1上。根据复制策略,数据的副本也会被存储在其他节点上。2.2.2虚拟节点和哈希环虚拟节点允许Cassandra更均匀地分布数据,避免了热点问题。哈希环是一个概念性的环,其中包含了所有节点的虚拟节点。每个虚拟节点在环上占据一个位置,数据根据其哈希值被放置在环上的相应位置。2.2.3复制策略Cassandra提供了多种复制策略,包括SimpleStrategy和NetworkTopologyStrategy。SimpleStrategy在所有节点上均匀地复制数据,而NetworkTopologyStrategy允许根据数据中心的位置来调整复制因子,以优化读写性能和数据持久性。通过上述内容,我们了解了Cassandra的基本架构,包括其数据模型和列族的概念,以及分布式架构和数据分布的机制。这为理解Cassandra的读写操作和数据一致性提供了基础。3Cassandra的读操作3.1读取流程详解在Cassandra中,读取操作遵循一个分布式且容错的流程。当客户端发起读取请求时,以下步骤将被执行:客户端发送读请求:客户端向Cassandra集群中的任意节点发送读取请求。请求中包含键空间、列族、主键以及读取一致性级别。协调节点处理请求:接收请求的节点成为协调节点。它负责处理请求并收集结果。协调节点首先检查本地是否包含所需数据。如果数据存在,它将直接返回;如果数据不存在或过期,它将向其他节点发送请求。数据收集:协调节点向其他节点发送请求,这些节点被称为参与者。参与者节点检查其本地副本是否包含所需数据,并将结果发送回协调节点。结果合并:协调节点收集所有参与者的响应,根据读取一致性级别合并结果。如果多个副本包含不同版本的数据,Cassandra将使用时间戳来确定哪个版本是最新的。返回结果:一旦收集到足够的数据,协调节点将结果返回给客户端。异常处理:如果在读取过程中遇到节点不可用的情况,Cassandra将根据配置的策略处理异常,如重试或返回部分结果。3.2读取一致性级别Cassandra提供了多种读取一致性级别,以满足不同场景下的需求。这些级别控制了读取操作需要从多少个副本中获取数据,以及在遇到节点不可用时的行为。以下是一些常见的读取一致性级别:ANY:只要有一个节点响应,读取操作就成功。这提供了最低的延迟,但可能返回过时的数据。ONE:至少需要一个节点响应。与ANY相似,但确保至少有一个节点的数据被读取。TWO、THREE:需要至少两个或三个节点响应。这增加了数据的可靠性,但可能增加延迟。QUORUM:需要超过半数的节点响应。这是默认的一致性级别,提供了良好的数据一致性和可用性平衡。ALL:需要所有副本节点响应。这提供了最高的数据一致性,但可能在节点不可用时导致读取失败。LOCAL_QUORUM:需要超过半数的本地数据中心节点响应。这在多数据中心部署中使用,以减少跨数据中心的网络延迟。EACH_QUORUM:在每个数据中心中都需要超过半数的节点响应。这在多数据中心部署中提供了一致性保证。3.2.1示例:设置读取一致性级别importorg.apache.cassandra.thrift.Cassandra;
importorg.apache.cassandra.thrift.ConsistencyLevel;
importorg.apache.cassandra.thrift.KeyRange;
importorg.apache.cassandra.thrift.SlicePredicate;
importorg.apache.cassandra.thrift.SliceRange;
importorg.apache.cassandra.thrift.ColumnParent;
importorg.apache.cassandra.thrift.InvalidRequestException;
importorg.apache.cassandra.thrift.UnavailableException;
importorg.apache.cassandra.thrift.TimedOutException;
importorg.apache.cassandra.thrift.NotFoundException;
//创建Cassandra客户端
Cassandra.Clientclient=...;
//设置读取一致性级别为QUORUM
ConsistencyLevelconsistencyLevel=ConsistencyLevel.QUORUM;
//定义读取的列族和键
ColumnParentcolumnParent=newColumnParent("column_family");
SlicePredicateslicePredicate=newSlicePredicate();
slicePredicate.setSlice_range(newSliceRange("start","finish",false,1024));
//发起读取请求
try{
List<ColumnOrSuperColumn>result=client.get_slice("key",columnParent,slicePredicate,consistencyLevel);
//处理结果
}catch(InvalidRequestExceptione){
//处理无效请求异常
}catch(UnavailableExceptione){
//处理不可用异常
}catch(TimedOutExceptione){
//处理超时异常
}catch(NotFoundExceptione){
//处理未找到异常
}3.3读取异常处理在分布式系统中,读取操作可能会遇到各种异常,如节点不可用、超时或数据不存在。Cassandra提供了一套机制来处理这些异常:UnavailableException:当没有足够的节点响应以满足读取一致性级别时,Cassandra将抛出此异常。客户端可以配置重试策略或降低一致性级别以处理这种情况。TimedOutException:当读取操作超时,Cassandra将抛出此异常。这通常发生在网络延迟或节点过载的情况下。NotFoundException:当请求的数据在所有副本中都不存在时,Cassandra将抛出此异常。这可能是因为数据从未被写入,或者已经被删除。3.3.1示例:处理读取异常try{
List<ColumnOrSuperColumn>result=client.get_slice("key",columnParent,slicePredicate,consistencyLevel);
//处理结果
}catch(UnavailableExceptione){
System.out.println("UnavailableException:"+e.getMessage());
//可以选择重试或降低一致性级别
}catch(TimedOutExceptione){
System.out.println("TimedOutException:"+e.getMessage());
//可以选择重试或增加超时时间
}catch(NotFoundExceptione){
System.out.println("NotFoundException:"+e.getMessage());
//数据不存在,可以处理或记录
}在处理这些异常时,客户端可以配置重试策略,如指数退避,以避免在短暂的网络问题或节点过载时立即失败。此外,客户端还可以根据业务需求调整读取一致性级别,以在数据一致性和系统可用性之间找到平衡点。4Cassandra的写操作4.1写入流程详解在Cassandra中,写操作遵循一个分布式且容错的流程,确保数据的高可用性和一致性。当客户端向Cassandra发送写请求时,以下步骤将被执行:确定目标节点:客户端首先确定数据应写入的分区键(PartitionKey)对应的主节点(PrimaryNode)。写入请求:客户端将写请求发送给主节点。写入日志:主节点在接收到写请求后,首先将其写入到本地的提交日志(CommitLog)中,以确保即使在节点崩溃的情况下,数据也不会丢失。更新Memtable:随后,数据被添加到内存中的Memtable。Memtable是按分区键排序的内存数据结构,用于缓存写入操作。持久化到SSTable:当Memtable达到一定大小时,它会被刷新到磁盘上的SSTable(SortedStringTable)。SSTable是Cassandra中用于存储数据的持久化文件。写入一致性:在写入过程中,Cassandra支持不同的写入一致性级别,以满足不同场景下的需求。复制数据:根据配置的复制策略,主节点将数据复制到其他副本节点上,以确保数据的冗余和高可用性。返回确认:一旦数据被成功写入到所有必要的节点上,主节点将向客户端返回写操作成功的确认。4.1.1示例代码fromcassandra.clusterimportCluster
#连接Cassandra集群
cluster=Cluster([''])
session=cluster.connect()
#创建Keyspace
session.execute("CREATEKEYSPACEIFNOTEXISTStestWITHreplication={'class':'SimpleStrategy','replication_factor':3};")
#使用Keyspace
session.set_keyspace('test')
#创建表
session.execute("CREATETABLEIFNOTEXISTSusers(idUUIDPRIMARYKEY,nametext,ageint);")
#插入数据
user_id=uuid.uuid4()
session.execute("INSERTINTOusers(id,name,age)VALUES(%s,%s,%s)USINGCONSISTENCYONE;",(user_id,"JohnDoe",30))
#关闭连接
cluster.shutdown()在上述代码中,我们首先连接到Cassandra集群,然后创建一个Keyspace和表。插入数据时,我们使用了CONSISTENCYONE一致性级别,这意味着写操作至少要在一个节点上成功即可返回确认。4.2写入一致性级别Cassandra提供了多种写入一致性级别,以控制写操作在集群中的传播范围。这些级别包括:ANY:写操作在任意节点上成功即可返回确认。ONE:写操作至少在一个节点上成功即可返回确认。TWO:写操作至少在两个节点上成功才返回确认。THREE:写操作至少在三个节点上成功才返回确认。QUORUM:写操作在大多数副本节点上成功才返回确认。ALL:写操作在所有副本节点上成功才返回确认。LOCAL_QUORUM:写操作在本地数据中心的大多数副本节点上成功才返回确认。EACH_QUORUM:写操作在每个数据中心的大多数副本节点上成功才返回确认。4.2.1示例代码#使用QUORUM一致性级别插入数据
session.execute("INSERTINTOusers(id,name,age)VALUES(%s,%s,%s)USINGCONSISTENCYQUORUM;",(user_id,"JaneDoe",28))在本例中,我们使用了QUORUM一致性级别,这意味着写操作需要在大多数副本节点上成功才能返回确认。4.3写入异常处理与数据冗余Cassandra在写入过程中可能会遇到各种异常,如节点不可用、网络问题等。为了处理这些异常,Cassandra提供了重试机制和数据冗余策略。4.3.1异常处理当写操作遇到异常时,Cassandra客户端可以配置重试策略,如重试次数、重试间隔等,以确保数据最终能够被成功写入。4.3.2数据冗余Cassandra通过数据复制来实现数据冗余,确保即使部分节点失败,数据仍然可访问。复制策略(如SimpleStrategy、NetworkTopologyStrategy等)决定了数据在集群中的分布方式。4.3.3示例代码#使用NetworkTopologyStrategy创建Keyspace,设置不同数据中心的复制因子
session.execute("CREATEKEYSPACEIFNOTEXISTStestWITHreplication={'class':'NetworkTopologyStrategy','datacenter1':2,'datacenter2':1};")在本例中,我们使用NetworkTopologyStrategy创建了一个Keyspace,并设置了不同数据中心的复制因子,以实现数据的跨数据中心冗余。通过以上步骤和示例,我们可以看到Cassandra的写操作流程、一致性级别以及如何处理异常和实现数据冗余。这些机制共同确保了Cassandra在分布式环境下的数据持久性和一致性。5数据一致性保证5.1致性模型与CAP理论在分布式存储系统中,数据一致性是一个核心问题。CAP理论,由EricBrewer提出,阐述了在分布式系统中,Consistency(一致性)、Availability(可用性)和Partitiontolerance(分区容错性)这三个特性,最多只能同时实现两个。Cassandra选择牺牲一致性以保证可用性和分区容错性,这使得它在大规模数据处理和高并发场景下表现优异。5.1.1致性模型Cassandra采用了一种称为“最终一致性”的模型。这意味着在系统中进行写操作后,数据可能不会立即对所有读操作可见,但在一段时间后,所有节点上的数据将最终达到一致状态。这种模型允许系统在面对网络分区和高并发时,仍然能够提供服务。5.1.2CAP理论在Cassandra中的体现一致性(Consistency):Cassandra允许用户通过设置一致性级别来控制读写操作的一致性。例如,LOCAL_QUORUM一致性级别要求在本地数据中心的大多数节点上进行读写操作。可用性(Availability):即使在部分节点故障或网络分区的情况下,Cassandra仍然能够提供读写服务。分区容错性(Partitiontolerance):Cassandra设计时就考虑到了网络分区的可能性,能够在这种情况下继续运行。5.2Cassandra的一致性策略Cassandra提供了一套灵活的一致性策略,允许用户根据应用需求调整读写操作的一致性级别。这些策略包括:ANY:只要有一个节点响应,操作就认为成功。ONE:至少有一个节点响应,操作就认为成功。TWO、THREE:至少有两个或三个节点响应,操作才认为成功。QUORUM:大多数节点响应,操作才认为成功。LOCAL_QUORUM:本地数据中心的大多数节点响应,操作才认为成功。EACH_QUORUM:每个数据中心的大多数节点响应,操作才认为成功。SERIAL、LOCAL_SERIAL:在单个节点上进行串行操作,用于保证唯一性,如主键冲突检查。5.2.1示例:设置一致性级别//设置一致性级别为QUORUM
CONSISTENCYQUORUM;
//执行写操作
INSERTINTOkeyspace.table(key,value)VALUES('example_key','example_value')USINGCONSISTENCYQUORUM;
//执行读操作
SELECT*FROMkeyspace.tableWHEREkey='example_key'USINGCONSISTENCYQUORUM;5.3冲突解决与数据版本控制在分布式系统中,由于网络延迟或节点故障,可能会出现数据冲突。Cassandra通过数据版本控制和时间戳机制来解决冲突。5.3.1时间戳机制Cassandra为每个写操作分配一个时间戳,当多个写操作针对同一数据项时,时间戳较高的写操作将覆盖时间戳较低的写操作。时间戳可以是系统自动生成的,也可以由应用程序提供。5.3.2示例:使用时间戳解决冲突假设我们有两个节点,NodeA和NodeB,它们同时尝试更新同一行数据。//NodeA尝试更新数据
UPDATEkeyspace.tableSETvalue='value_A'WHEREkey='conflict_key'USINGTIMESTAMP100;
//NodeB尝试更新数据
UPDATEkeyspace.tableSETvalue='value_B'WHEREkey='conflict_key'USINGTIMESTAMP200;由于NodeB的写操作具有更高的时间戳,因此它将覆盖NodeA的写操作。5.3.3数据版本控制Cassandra通过维护数据的多个版本来处理冲突。每个版本都有一个时间戳,当读取数据时,Cassandra会返回时间戳最高的版本。此外,Cassandra还提供了TTL(TimeToLive)功能,允许数据在一定时间后自动过期,这有助于减少存储空间的使用。5.3.4示例:使用TTL//设置数据的TTL为一天
UPDATEkeyspace.tableSETvalue='temp_value',ttl=86400WHEREkey='ttl_key';
//一天后,数据将自动过期通过上述策略,Cassandra能够在保证高可用性和分区容错性的同时,提供数据一致性保证。6性能优化与最佳实践6.1读写性能调优在Cassandra中,读写性能的调优主要围绕以下几个关键点进行:6.1.1数据模型设计分区键选择:分区键决定了数据的分布,选择合适的分区键可以确保数据均匀分布,避免热点问题。列族和列的使用:合理设计列族和列,减少不必要的读写操作,可以显著提升性能。6.1.2索引和缓存索引:Cassandra支持二级索引,但使用时需谨慎,因为索引会增加写操作的开销。缓存:启用缓存可以减少磁盘I/O,提高读取速度,但需要根据数据访问模式和系统资源进行调整。6.1.3硬件和配置SSD:使用SSD而非HDD可以显著提高读写速度。内存配置:调整内存分配,确保足够的内存用于缓存和操作系统的缓冲区。6.1.4读写一致性级别一致性级别:选择合适的一致性级别可以在性能和数据一致性之间找到平衡点。6.1.5示例:调整读写一致性级别//Java示例代码,调整Cassandra的读写一致性级别
importcom.datastax.driver.core.Cluster;
importcom.datastax.driver.core.ConsistencyLevel;
importcom.datastax.driver.core.Session;
publicclassConsistencyLevelExample{
publicstaticvoidmain(String[]args){
//创建Cassandra集群连接
Clustercluster=Cluster.builder().addContactPoint("").build();
Sessionsession=cluster.connect();
//设置写一致性级别为QUORUM
session.execute("INSERTINTOkeyspace.table(key,value)VALUES('key1','value1')",
newWriteType().consistencyLevel(ConsistencyLevel.QUORUM));
//设置读一致性级别为LOCAL_QUORUM
ResultSetresults=session.execute("SELECT*FROMkeyspace.tableWHEREkey='key1'",
newReadType().consistencyLevel(ConsistencyLevel.LOCAL_QUORUM));
for(Rowrow:results){
System.out.println(row.getString("value"));
}
//关闭连接
session.close();
cluster.close();
}
}此示例展示了如何在Cassandra中设置读写一致性级别。QUORUM和LOCAL_QUORUM是两种常用的一致性级别,前者要求大多数节点确认写操作,后者则在本地数据中心内要求大多数节点确认读操作。6.2数据一致性与性能的权衡在分布式系统中,数据一致性与性能往往存在权衡。Cassandra通过提供不同的读写一致性级别,允许用户根据应用需求调整这一权衡。6.2.1强一致性优点:数据在所有节点上保持一致,适合对数据一致性要求高的场景。缺点:可能降低性能,特别是在网络延迟较高的情况下。6.2.2弱一致性优点:提高读写性能,减少网络延迟。缺点:在某些情况下,可能会出现数据不一致的情况。6.2.3示例:使用弱一致性级别进行写操作//Java示例代码,使用弱一致性级别进行写操作
importcom.datastax.driver.core.Cluster;
importcom.datastax.driver.core.ConsistencyLevel;
importcom.datastax.driver.core.Session;
publicclassWeakConsistencyWrite{
publicstaticvoidmain(String[]args){
//创建Cassandra集群连接
Clustercluster=Cluster.builder().addContactPoint("").build();
Sessionsession=cluster.connect();
/
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 现代物流技术与医疗物资保障体系
- 沟通技巧在教育工作中的创新应用
- 环保技术在现代城市建设中的应用
- 物流信息技术在商业领域的应用
- Unit 3 Where did you go?PartB (说课稿)-2023-2024学年人教PEP版英语六年级下册
- 2《烛之武退秦师》说课稿-2024-2025学年高一语文下学期同步说课稿(统编版必修下册)
- 2024新教材高中地理 第四章 区域发展战略 第二节 我国区域发展战略说课稿 湘教版必修第二册
- Unit3 Amazing animals(说课稿)-2024-2025学年人教PEP版(2024)英语三年级上册001
- 2024年高中化学 第三章 晶体结构与性质 章末整合说课稿 新人教版选修3
- 1《我是独特的》第二课时(说课稿)2023-2024学年统编版道德与法治三年级下册
- 2025年河南洛阳市孟津区引进研究生学历人才50人历年高频重点提升(共500题)附带答案详解
- 2025年度军人军事秘密保护保密协议与信息安全风险评估合同3篇
- 蛋鸡生产饲养养殖培训课件
- 数字化转型中的职业能力重构
- 运用PDCA降低住院患者跌倒-坠床发生率
- 2025届高中数学一轮复习专练:椭圆(含解析)
- 立春气象与生活影响模板
- 中国服装零售行业发展环境、市场运行格局及前景研究报告-智研咨询(2025版)
- 汽车车身密封条设计指南
- DB4101-T 121-2024 类家庭社会工作服务规范
- DB53∕T 1269-2024 改性磷石膏用于矿山废弃地生态修复回填技术规范
评论
0/150
提交评论