文档章节

hadoop 工作上的一些知识点总结

tuoleisi77
 tuoleisi77
发布于 2018/06/18 17:33
字数 4293
阅读 244
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

HDFS部分

  • 如果让你来运营一个hdfs集群,你会重点关注哪些性能指标?请说出原因

详情参考hadoop相关性能指标说明。这里列出一些hdfs的关键指标

(1)rpc相关

rpc.rpc.RpcQueueTimeAvgTimerpc平均队列时长

rpc.rpc.RpcProcessingTimeAvgTimerpc平均处理时长

rpc.rpc.CallQueueLengthrpc队列请求队列长度

rpc.rpc.NumOpenConnections:rpc连接数

直接反应rpc性能的指标,如果出现明显增多,则说明namenode的性能异常。

 

(2)jvm相关

jvm.JvmMetrics.MemHeapUsedMjvm使用堆内存大小

jvm.JvmMetrics.MemNonHeapUsedM jvm非堆内存使用大小

jvm.JvmMetrics.ThreadsBlocked:阻塞的线程数

jvm.JvmMetrics.ThreadsWaiting:无限期等待线程数

jvm.JvmMetrics.ThreadsTimedWaiting:等待线程数

 

(3)namespace相关

TotalFiles:总的文件数量

TotalBlocks:总的block数量

PercentUsed:集群hdfs使用百分比

BlockPoolUsedSpace:集群该namespacehdfs使用容量大小

NumLiveDataNodes:存活的DN数量

NumDeadDataNodes:丢失的DN数量

MissingBlocks:丢失的block数量

(4)datenode相关

ReadBlockOpAvgTime:读取block的平均时间

WriteBlockOpAvgTime:写数据块的平均时间

 

(5)

ugi.UgiMetrics.GetGroupsAvgTime:获取组信息平均时长

 

 

二,请列出客户端和namenode之间的通信协议,以及协议的常用方法和作用。

org.apache.hadoop.hdfs.protocol.ClientProtocol

 

常用接口

创建文件:创建一个新的文件

public HdfsFileStatus create(String src, FsPermission masked,

      String clientName, EnumSetWritable<CreateFlag> flag,

      boolean createParent, short replication, long blockSize,

      CryptoProtocolVersion[] supportedVersions)

      throws AccessControlException, AlreadyBeingCreatedException,

      DSQuotaExceededException, FileAlreadyExistsException,

      FileNotFoundException, NSQuotaExceededException,

      ParentNotDirectoryException, SafeModeException, UnresolvedLinkException,

      SnapshotAccessControlException, IOException;

 

追加文件:打开一个文件,用于在该文件上新增数据。

public LocatedBlock append(String src, String clientName)

      throws AccessControlException, DSQuotaExceededException,

      FileNotFoundException, SafeModeException, UnresolvedLinkException,

      SnapshotAccessControlException, IOException;

 

获取数据块位置:获取数据块的保存位置

  public LocatedBlocks getBlockLocations(String src,

                                         long offset,

                                         long length)

      throws AccessControlException, FileNotFoundException,

      UnresolvedLinkException, IOException;

 

报告坏块:当客户端发现获取的数据块有问题时,会报告给namenode

public void reportBadBlocks(LocatedBlock[] blocks) throws IOException

 

增加数据块:写入数据时,申请新的数据块

public LocatedBlock addBlock(String src, String clientName,

      ExtendedBlock previous, DatanodeInfo[] excludeNodes, long fileId,

      String[] favoredNodes)

      throws AccessControlException, FileNotFoundException,

      NotReplicatedYetException, SafeModeException, UnresolvedLinkException,

      IOException;

 

放弃申请的数据块:当写数据块出错误时,可以放弃该数据块

  public void abandonBlock(ExtendedBlock b, long fileId,

      String src, String holder)

      throws AccessControlException, FileNotFoundException,

      UnresolvedLinkException, IOException;

 

持久化数据:当需要关闭文件时,需要首先调用该函数,对数据进行持久化

  public void fsync(String src, long inodeId, String client,

                    long lastBlockLength)

      throws AccessControlException, FileNotFoundException,

      UnresolvedLinkException, IOException;

 

关闭文件:数据持久化之后,进行文件的关闭

  public boolean complete(String src, String clientName,

                          ExtendedBlock last, long fileId)

      throws AccessControlException, FileNotFoundException, SafeModeException,

      UnresolvedLinkException, IOException;

 

获取文件或者目录的信息:

public HdfsFileStatus getFileInfo(String src) throws AccessControlException,

      FileNotFoundException, UnresolvedLinkException, IOException;

 

获取目录的空间信息:

public ContentSummary getContentSummary(String path)

      throws AccessControlException, FileNotFoundException,

      UnresolvedLinkException, IOException;

 

设置文件/目录权限

public void setPermission(String src, FsPermission permission)

      throws AccessControlException, FileNotFoundException, SafeModeException,

      UnresolvedLinkException, SnapshotAccessControlException, IOException;

 

设置文件所属用户和组:

  public void setOwner(String src, String username, String groupname)

      throws AccessControlException, FileNotFoundException, SafeModeException,

      UnresolvedLinkException, SnapshotAccessControlException, IOException;

 

设置文件的修改时间和访问时间:

  public void setTimes(String src, long mtime, long atime)

      throws AccessControlException, FileNotFoundException,

      UnresolvedLinkException, SnapshotAccessControlException, IOException;

 

设置文件副本个数:

  public boolean setReplication(String src, short replication)

      throws AccessControlException, DSQuotaExceededException,

      FileNotFoundException, SafeModeException, UnresolvedLinkException,

      SnapshotAccessControlException, IOException;

 

删除文件/目录:

  public boolean delete(String src, boolean recursive)

      throws AccessControlException, FileNotFoundException, SafeModeException,

      UnresolvedLinkException, SnapshotAccessControlException, IOException;

 

文件/目录重命名:

  public boolean rename(String src, String dst)

      throws UnresolvedLinkException, SnapshotAccessControlException, IOException;

 

创建目录:

  public boolean mkdirs(String src, FsPermission masked, boolean createParent)

      throws AccessControlException, FileAlreadyExistsException,

      FileNotFoundException, NSQuotaExceededException,

      ParentNotDirectoryException, SafeModeException, UnresolvedLinkException,

      SnapshotAccessControlException, IOException;

 

获取一个目录下的项目:

  public DirectoryListing getListing(String src,

                                     byte[] startAfter,

                                     boolean needLocation)

      throws AccessControlException, FileNotFoundException,

      UnresolvedLinkException, IOException;

 

管理方法:

设置目录配额:

  public void setQuota(String path, long namespaceQuota, long diskspaceQuota)

      throws AccessControlException, FileNotFoundException,

      UnresolvedLinkException, SnapshotAccessControlException, IOException;

 

设置安全模式:

  public boolean setSafeMode(HdfsConstants.SafeModeAction action, boolean isChecked)

      throws IOException;

 

刷新节点:

public void refreshNodes() throws IOException;

 

保存image文件,并重置editlog

public void saveNamespace() throws AccessControlException, IOException;

 

三,请简述hdfs dfs -du 操作的内部细节,结合实际场景描述一下该操作的代价。

Hdfs dfs –du统计指定文件或目录下各个子项目的容量。-s参数:合计统计。-h参数:转换成易读形式显示

 

实现细节:

解析参数验证合法性——>通过rpc调用namenode远程方法——> FSNamesystem. getContentSummary(final String srcArg)——>返回结果

 

FSNamesystem. getContentSummary(final String srcArg)方法的实现比较复杂。他会递归统计各个项目的大小,并且在统计用量的时候会给namespace加锁。所以在du一个非常大的目录时,读锁的时间会很长,在此期间hdfs不提供写服务,会造成写请求挤压,进而导致整个集群性能下降。

1,上锁:读锁允许namespace提供读服务,但是禁止写锁的访问。

 

2,递归

 

 

 

四,hdfs为什么不适合存放大量小文件,小文件过多的常见解决方案是什么?

 

小文件:不满足一个块大小并且文件本身非常小的文件(比如大量不大1MB的文件),具体的阈值可以根据hdfs的具体情况而定。

 

小文件过多的影响:

(1)文件的元数据信息保存在namenode的内存中,而具体的数据保存在datanode的磁盘上。小文件过多,会出现hdfs的物理空间很充足但是namenode的内存空间很紧张。使得在管理同等数据量的情况下,namende的压力显著增大,造成datanode空间浪费。

(2)在没有进行输入合并的mr任务中,针对每个文件都会启动一个map任务读取数据。小文件过多,会导致处理相同数据量的任务时map任务个数大大增加。增大集群压力的同时还会降低任务运行效率。

 

常见解决方案:

(1)文件归档: Hadoop archives

(2)冷数据压缩

(3)更改文件的写出方式:比如通过写HBase的方式进行数据的写入,例如将文件名和文件内容,作为具体数据直接写入hbase

 

 

五,请概述namenode的ha机制,尽可能多的列出会引发namenode的主备切换的原因,以及ha切换对集群有何影响。

 

HA机制:采用共享存储的原理,zookeeper用来做主从选举,JournalNodes用来做编辑日志文件的存储。

架构图如下

 

主进程是zkfc(ZKFailoverController),有两个关键服务HealthMonitorActiveStandbyElector

HealthMonitor:监控namenode的状态

ActiveStandbyElector主从选举,利用了zookeeper临时节点的特性

Zkfc会在zookeeper中创建两个节点:

(1)ActiveStandbyElectorLock:临时节点,用来做主从选举

(2)ActiveBreadCrumb:永久节点,存放当前处于active namenode的节点信息,主要用来防止脑裂。

 

过程:

主从竞争:当namenode启动后,均会将自身状态置为standby,然后尝试着在zookeeper上创建ActiveStandbyElectorLock 临时目录,zookeeper可以保证只有一个请求创建成功,其它的请求失败。创建成功的namenode,会将自身状态转换为active,并将自身信息写入ActiveBreadCrumb 节点。创建ActiveStandbyElectorLock失败的namenode保持自身的standby状态不变,然后在ActiveStandbyElectorLock注册watcher监听该节点状态。

 

主从切换:当HealthMonitor检测到namenode故障时,如果需要进行切换,则会断开zookeeper的连接释放ActiveStandbyElectorLock节点,然后将自身状态设置为standby,同时将ActiveBreadCrumb里面的数据删除,休息一定的时间再次加入选举。在休息的期间,其它节点一般会抢到ActiveStandbyElectorLock锁,并成为active。

当active namenode正常运行,但是zkfc和zookeeper由于心跳超时导致ActiveStandbyElectorLock节点释放,但是ActiveBreadCrumb中的数据没有删除成功时。其它节点如果抢到ActiveStandbyElectorLock锁,会首先判断ActiveBreadCrumb中的数据,发现是另外一个节点数据,会尝试通过rpc请求将原先的active namenode置为standby,如果原先的active namenode特别繁忙,对该rpc请求无法做出相应时。则zkfc会根据dfs.ha.fencing.methods配置方法进行处理(一般是,ssh远程执行fuser暴力杀死namenode进程)

 

导致namenode切换常见原因:

总结起来说,只要是zkfc释放了zookeeper中的ActiveStandbyElectorLock临时节点,就会导致切换。zookeeper临时节点的特性:zk和客户端的会话结束,临时节点删除。所以要么是zkfc主动释放了临时节点,要么是会话结束zk自动删除临时节点。根据这两个线索,结合namenode和zkfc就可以总结出namenode切换的常见原因

  1. zkfc进程挂掉;(人为杀死,系统故障等)
  2. zkfc和zookeeper连接超时;(网络故障,zkfc持续full gc等)
  3. zkfcHealthMonitor检测到namenode故障,需要进行切换;(namenode自身故障,健康检测rpc请求超时,网络故障等等)

HAServiceProtocol协议的两个方法:getServiceStatus和monitorHealth

  1. 手工切换

 

Ha切换对集群的影响:

  1. 切换过程中对hdfs服务无法访问
  2. 如果切换前后均是一主一从正常运行。要根据客户端对namenode访问顺序的配置和namenode负载分别分析。

示例:如果namendoe负载很大,而且切换后,导致客户端先访问了standby namenode,那么hdfs效率会明显降低。

 

 

 

 

YARN部分

一, GBD平台队列配置中支持对oozie任务个数的并发限制,请问是基于什么原因要这么做?这样做的优缺点是什么?如果不这样做,你有其它办法吗?

<queue name="default">

        <maxRunningApps>10</maxRunningApps>

        <maxRunningOozieApps>5</maxRunningOozieApps>

 

        <minResources>0mb, 0vcores</minResources>

        <maxResources>184320mb, 60vcores</maxResources>

        <schedulingPolicy>DRF</schedulingPolicy>

        <maxAMShare>-1.0</maxAMShare>

        <weight>1.0</weight>

        <aclSubmitApps>hadoop,oozie</aclSubmitApps>

        <aclAdministerApps>hadoop,oozie</aclAdministerApps>

      </queue>

 

原因:利用oozie提交shell action任务时,oozie会将任务封装到一个只有一个map的mr任务(oozie launch任务),在该map中执行具体的逻辑。当我们写的shell脚本中需要启动新的application时(比如:hive –e ”select count(1) from dual”),就会出现一个yarn application中启动新的yarn application。因为队列资源和任务个数的限制,当oozie launch用尽了队列资源,或者达到了队列任务个数限制。那么oozie launch中则无法启动新的application任务,导致队列死锁。

优点:可以解决队列死锁问题,配置简单。

缺点:(1)有很大概率造成资源浪费。为了避免死锁,我们要确保当oozie launch任务个数达到限制时,队列资源要有大部分的剩余。因为我们无法判断该oozie任务中是否会启动新的application,所以当大量oozie任务并发时会造成资源浪费。(2)当队列中oozie任务和非oozie任务同时运行时,如果队列资源用满,oozie任务将无法启动子application直到有非oozie任务运行完毕腾出资源,这样会造成oozie任务的延迟。

其它解决办法:

oozie提交任务时,分别指定oozie.launcher.mapreduce.job.queuename和mapreduce.job.queuename参数,使得oozie launcher和实际的执行任务运行在不同队列。

 

 

 

 

二,在fairscheduler下,尽可能列举出哪些情况会造成某些任务一直处于ACCEPTED状态。如果遇到这种情况,你会从哪几个方面进行处理?

applicationmaster状态机如下:

 

Yarn状态机的特性:状态机处于某一状态时,只有在接收到相应的事件时才会进行转改的转换。根据rmapp状态机图,处于accepted状态的任务只有在接受到如下事件之一时才会进行状态的切换(RMAppEventType.ATTEMPT_REGISTERED, RMAppEventType.ATTEMPT_FAILED, RMAppEventType.ATTEMPT_FINISHED, RMAppEventType.KILL等)。在这里我们只关心ACCEPTED状态到RUNNING状态的切换,即是RMAppEventType.ATTEMPT_REGISTERED事件。

 

结合代码分析,正常情况下,应用在进入ACCEPTED状态和接收到ATTEMPT_REGISTERED之间主要做了如下工作:

  1. 新建一个RMAppAttemptImpl,并给他一个Start信号。
  2. 接下来就进入了RMAppAttemptImpl的生命周期。从NEW一直到LAUNCHED状态。
  3. RMAppAttemptImpl运行到LAUNCHED状态时会向RMApp回传ATTEMPT_REGISTERED事件,然后RMApp才会进入到RUNNING状态。

其中RMAppAttemptImpl从NEW到LAUNCHED之间主要做了如下工作:

  1. RMAppAttemptImpl向resourcemanager进行注册,调用ApplicationMasterProtocol的registerApplicationMaster方法
  2. RMAppAttemptImpl向调度器申请资源
  3. 调度器分配资源之后,会根据资源情况生成RMContainerImpl实例,并准备运行

其中

如果resourcemanager负载高,网络延迟等会造成(1)耗时增多

如果集群资源分配不合理或者资源使用负载高,第(2)步会耗时增多

如果队列运行任务个数达到限制或者application master占用资源达到限制,第(2)步会耗时增多,直到满足条件

如果am和nm之间网络延迟会造成(3)步耗时增多

 

 

 

 

三,Gbd平台上在使用oozie提交任务(特别是spark任务)的时候经常出现如下异常,请问是什么原因,该如何处理?

Container [pid=9775,containerID=container_1493900293742_1660_01_000002] is running beyond physical memory limits. Current usage: 3.0 GB of 3 GB physical memory used; 31.0 GB of 12.6 GB virtual memory used. Killing container. Dump of the process-tree for container_1493900293742_1660_01_000002 : |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE |- 10092 10085 9775 9775 (java) 11310 856 29477392384 646254 /usr/lib/jdk/bin/java -cp /appcom/spark-config/:/appcom/spark/lib/spark-assembly-1.6.1-hadoop2.6.0.jar:/appcom/spark/lib/datanucleus-rdbms-3.2.9.jar:/appcom/spark/lib/datanucleus-api-jdo-3.2.6.jar:/appcom/spark/lib/datanucleus-core-3.2.10.jar:/appcom/hadoop-config/:/appcom/hadoop-config/

 

原因:我们平台是将spark任务封装成shell脚本通过oozie shell action提交的。所以oozie launcher任务相当于spark的driver。因为oozie launcher任务是一个单map的mr任务,平台默认一个map的内存空间为3G,经常不满足spark driver对内存的要求。

处理:使用oozie提交spark任务时,通过配置ozie.launch.mapreduce.map.memory.mb参数,调大内存配置

 

 

 

四,请列出ResourceManager和ApplicationMaster之间的通信协议,以及协议的常用方法和作用。

org.apache.hadoop.yarn.api.ApplicationMasterProtocol

 

am向rm注册:

  public RegisterApplicationMasterResponse registerApplicationMaster(

      RegisterApplicationMasterRequest request)

  throws YarnException, IOException;

 

am向rm申请资源:

  public AllocateResponse allocate(AllocateRequest request)

  throws YarnException, IOException;

 

am向rm报告应用结束:

  public FinishApplicationMasterResponse finishApplicationMaster(

      FinishApplicationMasterRequest request)

  throws YarnException, IOException;

 

五,请概述resourcemanager的ha机制,尽可能多的列出会引发resourcemanager的主备切换的原因,以及ha切换对集群有何影响。

 

 

ResourceManager的ha也是采用共享存储的原理:一般的做法是配置一个zookeeper集群用来进行主从选举和任务状态信息的存储。主从选举依然采用zookeeper临时节点的特性,任务状态信息的存储则是为了进行任务的恢复。

不像hdfs有一个专门的zkfc进程来进行ha的管理,resourcemanager的ha关机进程是内嵌在自身服务当中的。

选举服务:

org.apache.hadoop.yarn.server.resourcemanager.EmbeddedElectorService

存储服务

接口:org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore

我们选择的实现:org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore

 

zookeeper相关节点:

ActiveStandbyElectorLock:临时节点,进行主从选举

ActiveBreadCrumb:持久节点,存放当前active数据

rmstore:存放rm和application状态信息,便于恢复

 

选举过程:

Rm启动后,先将自身状态置为standby状态。然后初始化EmbeddedElectorService服务(建立zookeeper连接,初始化相关节点),之后进入选举。选举方法是尝试在zookeeper中创建一个临时节点ActiveStandbyElectorLock,zookeeper可以确保只有一个请求可以创建成功。如果创建成功则说明选举成功,然后会将自身状态设置为active并启动相关服务(RMActiveServices),并且将自身信息写入ActiveBreadCrumb节点。如果创建临时节点失败,则说明选举失败,保持自身standby状态不变,同时向ActiveStandbyElectorLock注册watcher,监听该节点状态。

 

主从切换:active resourcemanager故障时(服务挂掉),则会断开zookeeper的连接释放ActiveStandbyElectorLock节点,然后将自身状态设置为standby,同时将ActiveBreadCrumb里面的数据删除。Standby resourcemanager监控到ActiveStandbyElectorLock节点被删除,则会去创建它,一旦创建成功接代表选举成功。接下来就会将自身状态置为active并启动相关服务(RMActiveServices),将自身信息写入ActiveBreadCrumb中。

注:我们目前使用的hadoop版本resourcemanager的ha没有fence机制

 

造成切换的原因:

总结起来说,只要是resourcemanager释放了zookeeper中的ActiveStandbyElectorLock临时节点,就会导致切换。zookeeper临时节点的特性:zk和客户端的会话结束,临时节点删除。所以要么是resourcemanager主动释放了临时节点,要么是会话结束zk自动删除临时节点。根据这两个线索,结合resourcemanager和EmbeddedElectorService就可以总结出resourcemanager切换的常见原因。

(1) resourcemanager进程挂掉;(人为杀死,系统故障,resourcemanager产生致命异常等)

(2) resourcemanager和zookeeper连接超时;(网络故障等)

(3)手工切换

 

Ha切换对集群的影响:

(1)切换过程中yarn服务无法访问

(2)rm切换会导致任务状态的重新加载(从zookeeper中读取任务状态),container级别的进度没办法恢复只能重跑,会导致任务的稍微延迟。

  1. 如果切换前后均是一主一从正常运行。要根据客户端对resourcemanager访问顺序的配置和namenode负载分别分析,同namenode。

 

 

tuoleisi77
粉丝 4
博文 28
码字总数 43810
作品 0
深圳
程序员
私信 提问
加载中
请先登录后再评论。
CDH5: 使用parcels配置lzo

一、Parcel 部署步骤 1 下载: 首先需要下载 Parcel。下载完成后,Parcel 将驻留在 Cloudera Manager 主机的本地目录中。 2 分配: Parcel 下载后,将分配到群集中的所有主机上并解压缩。 3 激...

cloud-coder
2014/07/01
6.8K
1
Hbase的Windows访问接口库--libhbase4win

libhbase4win是基于Thrift的Hbase的Windows访问接口库,开发工具使用VS2010,Hadoop版本为1.1.0,Hbase版本为0.94.0,thrift版本0.9.0,执行编译需要boost和thrift支持。...

张子良
2013/03/06
764
0
视图各种动画效果

自定义视图变换的各种动画效果。其中包括:CALayer、UIViewAnimation、CATransition、CABasicAnimation、CAKeyframeAnimation、CAAnimationGroup、CATransform3D各个知识点实现的动画效果,实...

匿名
2013/03/21
1.4K
0
高效 Java Web 开发框架--JessMA

JessMA 是功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hibernate、MyBatis 与 JDBC DAO 组件),集成了 Action 拦截...

伤神小怪兽
2012/11/13
9.2K
3
性能优化工具--Starfish

Starfish 是一个用于大数据分析的自调优系统,这是一托管 Github 上的项目,但目前访问是 404,不清楚为何。Starfish 相当于是一个性能优化工具,可让 Hadoop 用户和应用达到最佳性能,包含三...

匿名
2012/11/24
737
0

没有更多内容

加载失败,请刷新页面

加载更多

在视图控制器之间传递数据 - Passing Data between View Controllers

问题: I'm new to iOS and Objective-C and the whole MVC paradigm and I'm stuck with the following: 我是iOS和Objective-C以及整个MVC范例的新手,但我坚持以下几点: I have a view th......

fyin1314
22分钟前
6
0
Elasticsearch中mapping值得注意的一些小细节

简介 在Elasticsearch中mapping有很多可以配置的地方,但是使用多了就会发现,一般情况有关mapping最常用、也最实用的就简单的几个需要注意的地方。 下面就简单的介绍一下关于这些mapping中值...

trayvon
25分钟前
0
0
趣味编程-大鱼吃小鱼(5-7岁)

上一节老师教小朋友们编写了摘星星的游戏,今天跟着了老师学一下大鱼吃小鱼这个游戏吧!拿上你们的平板,跟着老师一起来做吧。 防止失联,点个“在看”!多多转发分享是老师录制视频的动力哦...

rainbow0124
今天
1
0
大集合!写作辅助工具

↑公众号关注 “Graph-AI” 专注于 图机器学习 大集合!论文写作辅助工具 这里收集论文写作过程中的辅助工具,比如包括Latex、画图、图表、语法、词语搭配、文献查找\下载\整理、翻译等。 会...

chengsen
08/01
0
0
SSL指纹的自定义功能-VMLogin 中文版防关联指纹浏览器在1.2.6.7 版本更新中加入

VMLogin 中文版指纹浏览器 在本次1.2.6.7 版本更新中加入了SSL指纹的自定义功能。 VMLogin 中文版浏览器:https://www.vmlogin.cc/ 主要可以设置 密码套件 的个数和顺序,这样能可以对抗一些...

VMlogin中文版防关联浏览器
37分钟前
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部