Quorum NWR

1.强一致性与最终一致性

1.1强一致性

强一致性能保证写操作完成后,任何后续访问都能读到更新后的值;强一致性可以保证从库有与主库一致的数据。如果主库突然宕机,我们仍可以保证数据完整。但如果从库宕机或网络阻塞,主库就无法完成写入操作。

1.2最终一致性

最终一致性只能保证如果对某个对象没有新的写操作了,最终所有后续访问都能读到相同的最近更新的值。开篇提到,容忍节点故障只是需要复制的一个原因。另两个原因是可扩展性和降低延迟。
单领导者的主从复制算法要求所有写入都由单个节点处理,但只读查询可以由任何节点处理。对于读多写少的场景,我们往往创建很多从库,并将读请求分散到所有的从库上去。这样能减小主库的负载,并允许向最近的节点发送读请求。当然这只适用于异步复制——如果尝试同步复制,则单个节点故障将使整个系统无法写入。
当用户从异步从库读取时,如果此异步从库落后,他可能会看到过时的信息。这种不一致只是一个暂时的状态——如果等待一段时间,从库最终会赶上并与主库保持一致。这称为最终一致性。
最终两个字用得很微妙,因为从写入主库到反映至从库之间的延迟,可能仅仅是几分之一秒,也可能是几个小时。

2.Quorum NWR 的三要素

2.1副本数

N 表示副本数,又叫做复制因子(Replication Factor)。也就是说,N 表示集群中同一份数据有多少个副本,就像下图的样子:

从图中你可以看到,在这个三节点的集群中,DATA-1 有 2 个副本,DATA-2 有 3 个副本,DATA-3 有 1 个副本。也就是说,副本数可以不等于节点数,不同的数据可以有不同的副本数。
在实现 Quorum NWR 的时候,你需要实现自定义副本的功能。也就是说,用户可以自定义指定数据的副本数,比如,用户可以指定 DATA-1 具有 2 个副本,DATA-2 具有 3 个副本,就像图中的样子。

2.2写一致性级别

W,又称写一致性级别(Write Consistency Level),表示成功完成 W 个副本更新,才完成写操作:

从图中你可以看到,DATA-2 的写副本数为 2,也就说,对 DATA-2 执行写操作时,完成了 2 个副本的更新(比如节点 A、C),才完成写操作。
那么有的人会问了,DATA-2 有 3 个数据副本,完成了 2 副本的更新,就完成了写操作,那么如何实现强一致性呢?如果读到了第三个数据副本(比如节点 B),不就可能无法读到更新后的值了吗?先继续看下面的内容。

3.读一致性级别

R,又称读一致性级别(Read Consistency Level),表示读取一个数据对象时需要读 R个副本。你可以这么理解,读取指定数据时,要读 R 副本,然后返回 R 个副本中最新的那份数据:

从图中你可以看到,DATA-2 的读副本数为 2。也就是说,客户端读取 DATA-2 的数据时,需要读取 2 个副本中的数据,然后返回最新的那份数据。
这里需要你注意的是,无论客户端如何执行读操作,哪怕它访问的是写操作未强制更新副本数据的节点(比如节点 B),但因为 W(2) + R(2) > N(3),也就是说,访问节点 B,执行读操作时,因为要读 2 份数据副本,所以除了节点 B 上的 DATA-2,还会读取节点 A 或节点 C 上的 DATA-2,就像上图的样子(比如节点 C 上的 DATA-2),而节点 A 和节点 C的 DATA-2 数据副本是强制更新成功的。这个时候,返回给客户端肯定是最新的那份数据。
你看,通过设置 R 为 2,即使读到前面问题中的第三份副本数据(比如节点 B),也能返回更新后的那份数据,实现强一致性了。

4.NWR组合

除此之外,关于 NWR 需要你注意的是,N、W、R 值的不同组合,会产生不同的一致性效果,具体来说,有这么两种效果:
当 W + R > N 的时候,对于客户端来讲,整个系统能保证强一致性,一定能返回更新后的那份数据。
当 W + R < N 的时候,对于客户端来讲,整个系统只能保证最终一致性,可能会返回旧数据。

本文转载于网络 如有侵权请联系删除

相关文章

  • 第八周一历届试题九宫幻方

    本文最后更新于1163天前,其中的信息可能已经有所发展或是发生改变。#include<iostream> #include<cstring> usingnamespacestd; intmain(){ ints1[3][3]={{4,9,2},{3,5,7},{8,1,6}}; ints2[3][3]={{2,9,4},{7,5,3},{6,1,8}}; ints3[3][3]={{8,1,6},{3,5,7},{4,9,2}}; ints4[3][3]={{8,3,4},{1,5,9},{6,7,2}}; ints5[3][3]={{4,3,8},{9,5,1},{2,7,6}}; ints6[3][3]={{6,7,2},{1,5,9},{8,3,4}}; ints7[3][3]={{6,1,8},{7,5,3},{2,9,4}}; ints8[3][3]={{8,1,6},{1,5,7},{4,9,2}}; ints9[3][3]={{2,9,4},{7,5,3},{6,1,8}}; ints10[3][3]={{2,7,6

  • 网站上的文字无法复制,花钱充会员解决?跟着我不花钱。

    1、点击[百度搜索]2、点击[计算机]3、按<Ctrl+P>键4、点击[文本]5、点击[复制] 6、点击[开始菜单]7、点击[Word]8、点击[文本]9、点击[粘贴]

  • 数值计算方法 Chapter4. 非线性方程求根

    数值计算方法Chapter4.非线性方程求根0.问题描述1.实根的对分法2.迭代法3.Newton迭代法4.弦截法0.问题描述给定一个复杂方程f(x)=0,如果直接求解其解析解非常复杂或者难以求解的话,那么可以通过数值求解的方法得到一定精度条件下的数值解。1.实根的对分法对分法使用的条件需要满足:f(x)在区间[a,b]上连续;f(a)\cdotf(b)<0;那么,f(x)在区间[a,b]中必然存在至少一个零点,我们可以使用二分法不断地迭代求解。给出python伪代码如下:defbisect_solve(fn,a,b,epsilon=1e-9): assert(fn(a)*fn(b)<0) whileb-a>=epsilon: m=(a+b)/2 iffn(m)*fn(a)>0: a=m eliffn(m)*fn(b)>0: b=m else: returnm return(a+b)/2复制2.迭代法迭代法的思路是说,将方程f(x)=0改写为方程x=\varphi(x)。此时,我们可以构造迭代关系x_{k+1}=\varphi(x_k),如果数列x_k收敛

  • 企点增长双涡轮|修内功、练外力,增长八步走

    怎样才能实现企业真正的增长?增长的方法又应该如何拆解到企业的战略当中?和众多企业一样,腾讯企点也在不断探索增长的解题思路。10月11日、10月14日,企点特邀知名专家大咖,作为特邀行业研究员,共聚《企点增长双涡轮》微课堂,探讨企业的增长,希望通过多方观点碰撞,拓展思想边界,帮助企业一把手明道优术。点击下方微课堂,解锁增长秘籍。增长新思路:有效获客应该做到这些点2018年,腾讯通过大数据抓取,发现企业界普遍关注的热词是“增长”,引发各界的高度关注。但是很多企业虽然知道要增长,却不知道要如何开始。2021年,腾讯企点携手埃森哲,共建双涡轮增长方法论。同时划出品《企点增长双涡轮》微课堂,特别邀请以下嘉宾围坐研讨。腾讯《企点增长双涡轮》微课堂出席嘉宾-得到APP《MOT体验设计课》主理人、《峰值体验》作者汪志谦-腾讯云副总裁,腾讯企点总经理张晔-《哈佛商业评论》中文版执行出品人齐馨-《SaaS创业路线图》作者吴昊-腾讯CSIG市场部营销技术专家高海燕-沙利文及头豹研究院分析师袁栩聪-埃森哲大中华区互动体验总监郑嘉楠-连续创业者,福布斯40under40,复歌CEO郭为各位特邀研究员以“体验增长

  • 游戏封包,你会了吗?

    一、前言 游戏想必大家应该都玩过吧,一般游戏的话会分为单击、网游、页游,手游;而这几种游戏也是有着本质的区别,单击游戏无需联网,页游直接在浏览器中玩,网游则是下载客户端才能玩,而手游则是在手机上玩,今天我们要跟大家讲的是游戏的封包。何为封包?其实就是在服务器和客户端进行通信时,将其截获然后修改数据的一种方法,其实也就是相当于中间人攻击,这跟我们之前学到的抓包工具有点相像,不过今天我们要讲的这个工具可比一般的抓包工具强大,它不仅可以截获数据,还能修改数据哦,不过它修改的数据并不能直接反馈给服务器并进行交互,而是直接进行一个信息的伪造,达到一个装逼的效果,下面来看下吧。二、wpe三件套下载这个工具,地址:,这里面包含了三个工具,如图:三、页游封包 首先打开ccproxy,如图:首先查看他的设置功能,如图: 设置成以上这样就对了,然后更改账号允许范围为全部,如图: 这些都设置好了之后我们打开easy2game,如图: 这一步搞定了之后,你以为就可以抓包360浏览器上的数据了吗,No,你还要设置代理服务器地址,如图: 这个设置好了之后,我们就可以打开wpe进行抓包了。下面打开wpe,如图: 选

  • 详解面试官经常问的SpringBoot启动流程机制

    引言对于Java语言中最流行的项目脚手架SpringBoot,相信很多程序员都和之前的我一样停留在会用却说不出它的启动流程的阶段,每次去好一点的甲方公司面试一旦面试官问到SpringBoot的详细启动流程是什么时都会很懵圈,大部分没有研究过SpringBoot框架源码的的小伙伴99%是答不上来的,然后面试官一句回去等消息吧直接凉凉。那么本文就带领还没有研究过SpringBoot框架源码的小伙伴们来捋一捋SpringBoot应用的启动流程机制。1SpringBoot启动的流程总览每一个SpringBoot程序都有一个主入口,这个主入口就是main方法,而main方法中都会调用SpringBootApplication.run方法,一个快速了解SpringBootApplication启动过程的好方法就是在run方法中打一个断点,然后通过Debug的模式启动工程,逐步跟踪了解SpringBoot源码是如何完成环境准备和启动加载bean的。查看SpringBootApplication.run方法的源码就可以发现SpringBoot启动的流程主要分为两大阶段:初始化SpringApplica

  • Oracle查询优化-07日期运算

    7.1加减日、月、年在oracle中,date类型可以直接加减天数,而加减月份要用add_months函数.selecta.hiredate雇用日期, a.hiredate+5加5天, a.hiredate-5减5天, add_months(hiredate,5)加5个月, add_months(hiredate,-5)减5个月, add_months(hiredate,5*12)加5年, add_months(hiredate,-5*12)减5年 fromempawhererownum<=1; 雇用日期加5天减5天加5个月减5个月加5年减5年 ----------------------------------------------------------------------------- 1980-12-171980-12-221980-12-121981-05-171980-07-171985-12-171975-12-17复制7.2加减时、分、秒上面讲过,date可以直接加减天数,那么1/24就是一小时,分钟与秒的加减类同。selecta.hiredate, a

  • 【Java中的集合类探究】08 HashSet和TreeSet探究

    what?原来是HashMap套了层皮!HashMap成终极蛇皮打工仔!我们知道HashMap有键和值,但在HashSet中值都是一个,就是Object而在HashMap中键只会保存一份,所以不会重复。再看看TreeSet:再次破案,就是TreeMap上面套层皮...到此为止,集合类介绍的就差不多了,我还会写一个堆这个数据结构。之后还可能在并发的部分再反过来使用到集合里的东西~

  • express处理文件上传

    在用express开发时,有时候我们需要接收客户端上传的文件,express如果不借助第三方包处理上传文件比较复杂,所以我们使用formidable这个npm包。formidable这个npm包是做什么用的呢?其官网解释如下:ANode.jsmoduleforparsingformdata,especiallyfileuploads.官网实例代码如下:constexpress=require('express'); constformidable=require('formidable'); constpath=require('path'); constfs=require('fs'); constapp=express(); app.post('/api/upload',(req,res,next)=>{ constform=formidable({multiples:true,uploadDir:path.join(__dirname,'../..',&

  • 笔记 | GWAS 操作流程2-4:哈温平衡检验

    「什么是哈温平衡?」❝哈迪-温伯格(Hardy-Weinberg)法则哈迪-温伯格(Hardy-Weinberg)法则是群体遗传中最重要的原理,它解释了繁殖如何影响群体的基因和基因型频率。这个法则是用Hardy,G.H(英国数学家)和Weinberg,W.(德国医生)两位学者的姓来命名的,他们于同一年(1908年)各自发现了这一法则。他们提出在一个不发生突变、迁移和选择的无限大的随机交配的群体中,基因频率和基因型频率将逐代保持不变。---百度百科 ❞「怎么做哈温平衡检验?」❝「卡方适合性检验!」,一个群体是否符合这种状况,即达到了遗传平衡,也就是一对等位基因的3种基因型的比例分布符合公式:p2+2pq+q2=1,p+q=1,(p+q)2=1.基因型MM的频率为p2,NN的频率为q2,MN的频率为2pq。MN:MN:NN=P2:2pq:q2。MN这对基因在群体中达此状态,就是达到了遗传平衡。如果没有达到这个状态,就是一个遗传不平衡的群体。但随着群体中的随机交配,将会保持这个基因频率和基因型分布比例,而较易达到遗传平衡状态。应用Hardy-Weinberg遗传平衡吻合度检验方法,把计算得到

  • 如何部署 MongoDB 集群

    MongoDB是一个领先的非关系型数据库管理系统,也是NoSQL运动的重要成员。MongoDB不是使用关系数据库管理系统(RDBMS)的表和固定模式,而是在文档集合中使用键值存储。它还支持许多在大型生产环境中进行水平扩展的选项。本文将带您构建MongoDB的集群。您需要至少六个节点,需要在每一个节点上安装MongoDB。并在每个服务器上进行保护措施。如果您还没有腾讯云的服务器,可以先点击这里进行免费套餐的试用。免费套餐包含企业版和个人版,超过11款热门产品和42款长期免费的云产品可以供您选择。如果您有长期搭建服务器的需求的话,可以点击这里进行服务器的购买,现在的促销力度很大哦。集群架构在开始之前,让我们回顾一下我们将要创建的设置的组件:配置服务器-存储群集其余部分的元数据和配置设置。在本指南中,为简单起见,我们将使用一个配置服务器,但在生产环境中,这应该是至少三个节点的副本集。查询路由器-mongos守护程序充当客户端应用程序和集群分片之间的接口。由于数据分布在多个服务器之间,因此需要将每个查询路由到存储给定信息的分片。查询路由器在应用程序服务器上运行。在本指南中,我们将只使用一个查询

  • KVM综合实验

    实验要求:使用命令行创建虚拟机进入虚拟机,配置selinuxip等,并关闭虚拟机为虚拟机制作快照在关闭虚拟机的情况向,修改主机名,并且将文件拷入到虚拟机中克隆出一个虚拟机在克隆出的虚拟机上创建差分盘,并且开启。使用两台主机,A主机为kvm虚拟化主机,B主机制作成nfs服务器B主机上的分享出的文件,在A上作成存储池,并在此存储池上创建一个存储卷在存储卷上安装操作系统为安装好的kvm虚拟添加一个桥接网卡。准备机器c,安装虚拟化环境,并且定义机器B中的资源池将机器A中的虚拟机,冷迁移到机器C中将机器A中的虚拟机,克隆一份到共享资源池中,并且开机,热迁移到机器C中 实验环境:1)首先需要将虚拟机的处理器开启虚拟化功能2)检查KVM模块是否安装3)查看CPU是否支持4)yum安装虚拟化软件并启动libvirtd服务5)关闭selinux以上实验环境就搭建完成了,下面开始根据要求创建和管理KVM虚拟机。1、使用命令行创建虚拟机1)首先我们创建好存储池/mykvm/kvm-vm,和镜像存储池/mykvm/iso2)然后把系统镜像cp到镜像存储池中(需要多等一会儿)3)在存储池/mykvm/kvm-

  • 腾讯云私有连接跨地域VPC间服务共享

    如果您VPC中部署的云服务需要共享给其他地域下的VPC访问,您可以使用私有连接和云联网服务。 背景信息VPC是您独有的云上私有网络,不同VPC之间默认完全隔离。您可以通过私有连接(PrivateLink)服务,实现腾讯云VPC与同地域其他VPC上安全稳定的访问连接,简化网络架构,避免公网访问服务带来的潜在安全风险。如果您需要跨地域提供VPC服务共享,那么可以结合云联网打通跨地域VPC通信,然后再共同使用私有连接服务使用方VPC的终端节点实现对服务提供方VPC中服务的访问。 使用私有连接PrivateLink,您需要创建终端节点服务和终端节点。在创建终端节点服务之前,您需要创建一个内网4层负载均衡实例,并创建监听器关联已经部署业务的云服务器实例,之后在创建终端节点服务时关联该负载均衡实例,此时终端节点服务将作为服务提供方的业务访问入口,供服务使用方创建的终端节点来申请连接,连接建立成功后,服务使用方即可访问服务提供方部署的业务服务。 场景示例本文以下图业务场景为例。某公司业务部署在成都地域VPC2中,现需要将该业务用共享给同地域下其他VPC1网络及重庆地域下的VPC3网络中的客户端访问,

  • java jdk 8反编译工具JD-GUI、procyon-decompiler、luyten、crf下载使用简介

    本文对常用的反编译工具进行简单介绍 JD-GUI、procyon-decompiler、luyten、crf   反编译工具分类 JD-GUI JDK7以及之前可以使用  JD-GUI,如果版本>=1.8各种问题 http://java-decompiler.github.io   procyon-decompiler 如果版本>=1.8,可以使用procyon-decompiler,不过是命令行界面 https://bitbucket.org/mstrobel/procyon/downloads/   luyten luyten是Procyon的GUI,只需要下载luyten即可,不用下载Procyon  https://github.com/deathmarine/Luyten 下载地址 https://github.com/deathmarine/Luyten/releases crf crf也可以支持更高版本 http://www.benf.org/other/cfr/   小结 如果你的版本

  • 调用webservice,解析xml属性值

    1、调用webservice try{ Stringendpoint="http://22.222.22.22:280/iss-ws/services/SyncUserInfo?wsdl"; //直接引用远程的wsdl文件 //以下都是套路 Serviceservice=newService(); Callcall=(Call)service.createCall(); call.setTargetEndpointAddress(endpoint); call.setOperationName("getUserForAll");//WSDL里面描述的接口名称 call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);//设置返回类型 StringxmlString=(String)call.invoke(newObject[]{}); JSONObjectjson=getXmlAttribute(xmlString,"shujuziyuan"); System.out.println(json.get("code

  • TCL的艰难生存之路

      “在互联网产品的基础上,各种软件应用将会成为未来手机业务发展的第三条腿,但是现在还没有露出来。”王激扬对记者说。   此外,在10月份,TCL团体公布将于美国思科成立8000万美元合资公司,投资商用云服务平台。前不久,一家“科天聪明云信息科技有限公司”在广州成立。   据记者了解,TCL通信新成立的移动互联网新兴业务中央业务范围包括移动增值业务、云平台、立异应用、电商平台、可穿着设备等多个领域。其中移动增值业务是通过应用、游戏、音乐等内容的分发、个性化推荐来聚合优质资源,为用户提供增值服务,为了支持TCL通信的电商战略,移动互联网新兴业务中央还将搭建面向全球的电商服务平台。   “我们今年景立了移动互联网新兴业务中央,整个互联网产品会在明年三四月份的时候有一个清楚的脉络出来,这将作为除了运营商发展外的第二条腿。”王激扬对记者说。   “去年,我们把电商当做电商,当做电子渠道,但到了今年春节的时候,我就和电商的团队单独坐下来聊,我告诉大家,实在市场上是看不到单独电商成功的任何机会的。”王激扬对记者坦言,电商上面是没有贸易模式的,不是拼价格的题目,而是一个产品仅靠炒作和营销,难以持续的

  • GCC编译选项Sanitier问题定位记录

    关键词:Addresssanitizer、Useafterfree、Heapbufferoverflow、Stackbufferoverflow、Memoryleak等等。 操作系统:Ubuntu16.04;g++(Ubuntu4.8.5-4ubuntu2)4.8.5;clangversion3.8.0-2ubuntu4(tags/RELEASE_380/final)。 1.Sanitizer简介 Sanitizers是谷歌发起的开源工具集,包括了AddressSanitizer,MemorySanitizer,ThreadSanitizer,LeakSanitizer,Sanitizers项目本是LLVM项目的一部分,但GNU也将该系列工具加入到了自家的GCC编译器中。GCC从4.8版本开始支持Address和ThreadSanitizer,4.9版本开始支持LeakSanitizer和UBSanitizer,这些都是查找隐藏Bug的利器。 AddressSanitizer检查地址相关问题,包括释放后使用、重复释放、堆溢出、栈溢出等等问题。 LeakSanitizer检查内存泄漏问题

  • gRPC官方文档(概览)

    文章来自gRPC官方文档中文版 概览 开始 欢迎进入gRPC的开发文档,gRPC一开始由google开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。本文档通过快速概述和一个简单的HelloWorld例子来向您介绍gRPC。你可以在本站发现更详细的教程和参考文档——文档将会越来越丰富。 快速开始 为了直观地着手运行gRPC,可以从你所选择的语言对应的快速开始入手,里面包含创建这个列子的安装指导、快速上手指南等更多内容。 C++ Java Go Python Ruby Node.js AndroidJava C# Objective-C PHP 你可以从这里找到gRPC的源码库。我们大多数例子都在源码库examples目录下。 gRPC是什么? 在gRPC里_客户端_应用可以像调用本地对象一样直接调用另一台不同的机器上_服务端_应用的方法,使得您能够更容易地创建分布式应用和服务。与许多RPC系统类似,gRPC也是基于以下理念:定义一个_服务_,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个gRPC服务器来处理客户端调用。在客户端拥有

  • 项目总结

    经过了这一个学期紧张的学习与两个冲刺周期之后,我们团队的软件工程项目划上了一个比较圆满的句号。此次软件工程结对开发任务中,我们团队分工比较明确,由张佳玮和赵新月编程能力较强的同学承担大部分主要的资料收集、软件设计、主要计算代码等部分的编写,由李杰和侯志龙承担团队博客的发布、任务板的制作、寻找测试用户、资料收集和部分代码的编写工作,总体来说,我们团队的团队协作情况进行的还不错。经过用户测试和询问老师的意见后,我们认为,我们的软件还需要在一下部分进行改进: 1.没有设计出用户数据库,无法保存用户运行的结果数据,不够方便。 2.收集的相关资料不够全面,缺少直观描述的图片与相关视频,不便于用户理解相关内容。 3.软件按钮比较少,界面设计不够好,应将按钮设计的更美观,再增加一些功能。

  • pyenv、ipython、jupyter的安装使用

    1.安装pyenv 参考文档:https://github.com/pyenv/pyenv-installer 1.1.在线安装方法 yuminstallgit-y #pyenv在安装python的时候是就地编译的,需要下面的依赖,需要提前安装一下。 yuminstallgccmakepatchgdbm-developenssl-develsqlite-develreadline-develzlib-develbzip2-devel-y idpython useraddpython idpython echo"python"|passwdpython--stdin su-python curl-Lhttps://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer|bash echo'exportPATH="/home/python/.pyenv/bin:$PATH"'>>~/.bash_profile echo'eval"$(pyenvinit-)"' >>~/.bash_pr

  • ProBuilder快速原型开发技术 ---不规则模型与材质

    ProBuilder开发模型的强大之处,还在于可以按照要求精确定制不规则模型、克隆镜像模型、给模型着色以及添加材质等,下面笔者就这几方面进行讲解。 一:定制不规则模型 PB有一个专门定制不规则模型的功能“NewPolyShape”,可以按照设计师的想法,定义任意图案的模型,或者更加确切的说是“画出”我们想要的模型,制作步骤如下: 第1步:为了开发一个精确的模型,首先需要有一个参照网格图。笔者采用10*10的一个Plane或者Cube对象(既:长10米*宽10米),具体参照下图。   第2步:设置Scens视图中的“世界坐标系”为“正交视图”,且为Top方式,详见上图。 第3步:选择PB操作面板上的“NewPolyShape”菜单项,绘制图形,如下图所示。 第4步:此时按住Alt键,倾斜视图角度,如下图效果。 第5步:点击绿色点,上提后形成立方体,下图笔者绘制了一个“长城”墙模型体。 二:克隆镜像模型 对于已经开发好的模型,有时候我们还常常需要这个模型的“镜像模型”,此种方式就像镜面倒影一样。这样我们在某些情况下,可以采用镜像的方式,来组合出一些意想不到的复杂建筑或者模

相关推荐

推荐阅读