• MongoDB副本集调整节点


    点击上方蓝字关注我

    77406ddb6b83fc81dee9257424f3f9f1.png

    MongoDB的副本集(Replica Set)是一个高可用性、可扩展性和冗余性的数据库解决方案。它能够确保数据库的高可用性,同时保障了数据的安全性。在本文中,我们将探讨如何在一个已经包含三个数据节点的副本集集群中,添加一个仲裁节点,并同时删除原先的一个数据节点。


    1. 副本集的基本概念
    MongoDB副本集由多个数据节点+若干个仲裁节点(可以没有)组成,其中一个数据节点被选举为主节点(Primary),其余节点为次要节点(Secondary)。在故障时,副本集会自动进行主节点的切换,确保服务的高可用性。副本集中的仲裁节点(Arbiter)不存储数据,仅用于选举过程,帮助副本集进行决策。

    例如,当前配置一个3节点的数据节点集群,组件集群命令如下:

    1. > use admin
    2. > rs.initiate( {_id: "test1",members: [{ _id: 0, host: "192.168.122.36:27017" },{ _id: 1, host: "192.168.122.36:27018" },{ _id: 2, host: "192.168.122.36:27019" } ] })

    31dedc88568c8d8436a7178aad72f7f8.png

    查看状态:

    1. test1:PRIMARY> use admin
    2. switched to db admin
    3. test1:PRIMARY> rs.status()
    4. {
    5. "set" : "test1",
    6. "date" : ISODate("2023-10-23T02:31:02.345Z"),
    7. "myState" : 1,
    8. "term" : NumberLong(1),
    9. "syncingTo" : "",
    10. "syncSourceHost" : "",
    11. "syncSourceId" : -1,
    12. "heartbeatIntervalMillis" : NumberLong(2000),
    13. "majorityVoteCount" : 2,
    14. "writeMajorityCount" : 2,
    15. "optimes" : {
    16. "lastCommittedOpTime" : {
    17. "ts" : Timestamp(1698028254, 1),
    18. "t" : NumberLong(1)
    19. },
    20. "lastCommittedWallTime" : ISODate("2023-10-23T02:30:54.919Z"),
    21. "readConcernMajorityOpTime" : {
    22. "ts" : Timestamp(1698028254, 1),
    23. "t" : NumberLong(1)
    24. },
    25. "readConcernMajorityWallTime" : ISODate("2023-10-23T02:30:54.919Z"),
    26. "appliedOpTime" : {
    27. "ts" : Timestamp(1698028254, 1),
    28. "t" : NumberLong(1)
    29. },
    30. "durableOpTime" : {
    31. "ts" : Timestamp(1698028254, 1),
    32. "t" : NumberLong(1)
    33. },
    34. "lastAppliedWallTime" : ISODate("2023-10-23T02:30:54.919Z"),
    35. "lastDurableWallTime" : ISODate("2023-10-23T02:30:54.919Z")
    36. },
    37. "lastStableRecoveryTimestamp" : Timestamp(1698028224, 3),
    38. "lastStableCheckpointTimestamp" : Timestamp(1698028224, 3),
    39. "electionCandidateMetrics" : {
    40. "lastElectionReason" : "electionTimeout",
    41. "lastElectionDate" : ISODate("2023-10-23T02:30:24.838Z"),
    42. "electionTerm" : NumberLong(1),
    43. "lastCommittedOpTimeAtElection" : {
    44. "ts" : Timestamp(0, 0),
    45. "t" : NumberLong(-1)
    46. },
    47. "lastSeenOpTimeAtElection" : {
    48. "ts" : Timestamp(1698028214, 1),
    49. "t" : NumberLong(-1)
    50. },
    51. "numVotesNeeded" : 2,
    52. "priorityAtElection" : 1,
    53. "electionTimeoutMillis" : NumberLong(10000),
    54. "numCatchUpOps" : NumberLong(0),
    55. "newTermStartDate" : ISODate("2023-10-23T02:30:24.912Z"),
    56. "wMajorityWriteAvailabilityDate" : ISODate("2023-10-23T02:30:25.497Z")
    57. },
    58. "members" : [
    59. {
    60. "_id" : 0,
    61. "name" : "192.168.122.36:27017",
    62. "health" : 1,
    63. "state" : 1,
    64. "stateStr" : "PRIMARY",
    65. "uptime" : 183,
    66. "optime" : {
    67. "ts" : Timestamp(1698028254, 1),
    68. "t" : NumberLong(1)
    69. },
    70. "optimeDate" : ISODate("2023-10-23T02:30:54Z"),
    71. "syncingTo" : "",
    72. "syncSourceHost" : "",
    73. "syncSourceId" : -1,
    74. "infoMessage" : "could not find member to sync from",
    75. "electionTime" : Timestamp(1698028224, 1),
    76. "electionDate" : ISODate("2023-10-23T02:30:24Z"),
    77. "configVersion" : 1,
    78. "self" : true,
    79. "lastHeartbeatMessage" : ""
    80. },
    81. {
    82. "_id" : 1,
    83. "name" : "192.168.122.36:27018",
    84. "health" : 1,
    85. "state" : 2,
    86. "stateStr" : "SECONDARY",
    87. "uptime" : 47,
    88. "optime" : {
    89. "ts" : Timestamp(1698028254, 1),
    90. "t" : NumberLong(1)
    91. },
    92. "optimeDurable" : {
    93. "ts" : Timestamp(1698028254, 1),
    94. "t" : NumberLong(1)
    95. },
    96. "optimeDate" : ISODate("2023-10-23T02:30:54Z"),
    97. "optimeDurableDate" : ISODate("2023-10-23T02:30:54Z"),
    98. "lastHeartbeat" : ISODate("2023-10-23T02:31:00.889Z"),
    99. "lastHeartbeatRecv" : ISODate("2023-10-23T02:31:01.443Z"),
    100. "pingMs" : NumberLong(0),
    101. "lastHeartbeatMessage" : "",
    102. "syncingTo" : "192.168.122.36:27017",
    103. "syncSourceHost" : "192.168.122.36:27017",
    104. "syncSourceId" : 0,
    105. "infoMessage" : "",
    106. "configVersion" : 1
    107. },
    108. {
    109. "_id" : 2,
    110. "name" : "192.168.122.36:27019",
    111. "health" : 1,
    112. "state" : 2,
    113. "stateStr" : "SECONDARY",
    114. "uptime" : 47,
    115. "optime" : {
    116. "ts" : Timestamp(1698028254, 1),
    117. "t" : NumberLong(1)
    118. },
    119. "optimeDurable" : {
    120. "ts" : Timestamp(1698028254, 1),
    121. "t" : NumberLong(1)
    122. },
    123. "optimeDate" : ISODate("2023-10-23T02:30:54Z"),
    124. "optimeDurableDate" : ISODate("2023-10-23T02:30:54Z"),
    125. "lastHeartbeat" : ISODate("2023-10-23T02:31:00.890Z"),
    126. "lastHeartbeatRecv" : ISODate("2023-10-23T02:31:01.446Z"),
    127. "pingMs" : NumberLong(0),
    128. "lastHeartbeatMessage" : "",
    129. "syncingTo" : "192.168.122.36:27017",
    130. "syncSourceHost" : "192.168.122.36:27017",
    131. "syncSourceId" : 0,
    132. "infoMessage" : "",
    133. "configVersion" : 1
    134. }
    135. ],
    136. "ok" : 1,
    137. "$clusterTime" : {
    138. "clusterTime" : Timestamp(1698028254, 1),
    139. "signature" : {
    140. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    141. "keyId" : NumberLong(0)
    142. }
    143. },
    144. "operationTime" : Timestamp(1698028254, 1)
    145. }

    此时可以用一个程序验证集群的可用情况:

    1. from pymongo import MongoClient
    2. from pymongo.errors import ConnectionFailure
    3. # MongoDB副本集的连接信息
    4. replica_set = "test1"
    5. mongo_host = ["192.168.122.36:27017""192.168.122.36:27018""192.168.122.36:27019"]  # 主机和端口号列表
    6. # 尝试连接MongoDB副本集
    7. try:
    8. client = MongoClient(mongo_host, replicaSet=replica_set, serverSelectionTimeoutMS=5000)
    9. db = client["testdb"]
    10. print("Successfully connected to MongoDB replica set.")
    11. collection = db['test1']
    12.     data = {"b":2}
    13. result = collection.insert_one(data)
    14. except ConnectionFailure:
    15. print("Failed to connect to MongoDB replica set. Please check your connection settings.")

    运行结果如下:

    e33d11f7fabdced4502342c29278f149.png

    查看数据库中运行结果:

    2eb01cc0682f2af3bf95cd9268b6ea92.png


    2. 添加节点
    要添加一个仲裁节点,我们需要在现有副本集中的任一节点上执行如下操作:

    rs.add( { host: "IP:PORT", arbiterOnly:true } )

    执行这个命令后,MongoDB将会在副本集中添加一个仲裁节点,增加了选主的稳定性,同时不会增加数据存储的压力。具体实际案例如下

    1. test1:PRIMARY> use admin
    2. switched to db admin
    3. test1:PRIMARY> rs.add( { host: "192.168.122.36:27020", arbiterOnly:true } )
    4. {
    5. "ok" : 1,
    6. "$clusterTime" : {
    7. "clusterTime" : Timestamp(1698030806, 1),
    8. "signature" : {
    9. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    10. "keyId" : NumberLong(0)
    11. }
    12. },
    13. "operationTime" : Timestamp(1698030806, 1)
    14. }
    15. test1:PRIMARY> rs.status();
    16. {
    17. "set" : "test1",
    18. "date" : ISODate("2023-10-23T03:13:32.511Z"),
    19. "myState" : 1,
    20. "term" : NumberLong(1),
    21. "syncingTo" : "",
    22. "syncSourceHost" : "",
    23. "syncSourceId" : -1,
    24. "heartbeatIntervalMillis" : NumberLong(2000),
    25. "majorityVoteCount" : 3,
    26. "writeMajorityCount" : 3,
    27. "optimes" : {
    28. "lastCommittedOpTime" : {
    29. "ts" : Timestamp(1698030806, 1),
    30. "t" : NumberLong(1)
    31. },
    32. "lastCommittedWallTime" : ISODate("2023-10-23T03:13:26.379Z"),
    33. "readConcernMajorityOpTime" : {
    34. "ts" : Timestamp(1698030806, 1),
    35. "t" : NumberLong(1)
    36. },
    37. "readConcernMajorityWallTime" : ISODate("2023-10-23T03:13:26.379Z"),
    38. "appliedOpTime" : {
    39. "ts" : Timestamp(1698030806, 1),
    40. "t" : NumberLong(1)
    41. },
    42. "durableOpTime" : {
    43. "ts" : Timestamp(1698030806, 1),
    44. "t" : NumberLong(1)
    45. },
    46. "lastAppliedWallTime" : ISODate("2023-10-23T03:13:26.379Z"),
    47. "lastDurableWallTime" : ISODate("2023-10-23T03:13:26.379Z")
    48. },
    49. "lastStableRecoveryTimestamp" : Timestamp(1698030805, 1),
    50. "lastStableCheckpointTimestamp" : Timestamp(1698030805, 1),
    51. "electionCandidateMetrics" : {
    52. "lastElectionReason" : "electionTimeout",
    53. "lastElectionDate" : ISODate("2023-10-23T02:30:24.838Z"),
    54. "electionTerm" : NumberLong(1),
    55. "lastCommittedOpTimeAtElection" : {
    56. "ts" : Timestamp(0, 0),
    57. "t" : NumberLong(-1)
    58. },
    59. "lastSeenOpTimeAtElection" : {
    60. "ts" : Timestamp(1698028214, 1),
    61. "t" : NumberLong(-1)
    62. },
    63. "numVotesNeeded" : 2,
    64. "priorityAtElection" : 1,
    65. "electionTimeoutMillis" : NumberLong(10000),
    66. "numCatchUpOps" : NumberLong(0),
    67. "newTermStartDate" : ISODate("2023-10-23T02:30:24.912Z"),
    68. "wMajorityWriteAvailabilityDate" : ISODate("2023-10-23T02:30:25.497Z")
    69. },
    70. "members" : [
    71. {
    72. "_id" : 0,
    73. "name" : "192.168.122.36:27017",
    74. "health" : 1,
    75. "state" : 1,
    76. "stateStr" : "PRIMARY",
    77. "uptime" : 2733,
    78. "optime" : {
    79. "ts" : Timestamp(1698030806, 1),
    80. "t" : NumberLong(1)
    81. },
    82. "optimeDate" : ISODate("2023-10-23T03:13:26Z"),
    83. "syncingTo" : "",
    84. "syncSourceHost" : "",
    85. "syncSourceId" : -1,
    86. "infoMessage" : "",
    87. "electionTime" : Timestamp(1698028224, 1),
    88. "electionDate" : ISODate("2023-10-23T02:30:24Z"),
    89. "configVersion" : 2,
    90. "self" : true,
    91. "lastHeartbeatMessage" : ""
    92. },
    93. {
    94. "_id" : 1,
    95. "name" : "192.168.122.36:27018",
    96. "health" : 1,
    97. "state" : 2,
    98. "stateStr" : "SECONDARY",
    99. "uptime" : 2597,
    100. "optime" : {
    101. "ts" : Timestamp(1698030806, 1),
    102. "t" : NumberLong(1)
    103. },
    104. "optimeDurable" : {
    105. "ts" : Timestamp(1698030806, 1),
    106. "t" : NumberLong(1)
    107. },
    108. "optimeDate" : ISODate("2023-10-23T03:13:26Z"),
    109. "optimeDurableDate" : ISODate("2023-10-23T03:13:26Z"),
    110. "lastHeartbeat" : ISODate("2023-10-23T03:13:32.393Z"),
    111. "lastHeartbeatRecv" : ISODate("2023-10-23T03:13:32.420Z"),
    112. "pingMs" : NumberLong(1),
    113. "lastHeartbeatMessage" : "",
    114. "syncingTo" : "",
    115. "syncSourceHost" : "",
    116. "syncSourceId" : -1,
    117. "infoMessage" : "",
    118. "configVersion" : 2
    119. },
    120. {
    121. "_id" : 2,
    122. "name" : "192.168.122.36:27019",
    123. "health" : 1,
    124. "state" : 2,
    125. "stateStr" : "SECONDARY",
    126. "uptime" : 2597,
    127. "optime" : {
    128. "ts" : Timestamp(1698030806, 1),
    129. "t" : NumberLong(1)
    130. },
    131. "optimeDurable" : {
    132. "ts" : Timestamp(1698030806, 1),
    133. "t" : NumberLong(1)
    134. },
    135. "optimeDate" : ISODate("2023-10-23T03:13:26Z"),
    136. "optimeDurableDate" : ISODate("2023-10-23T03:13:26Z"),
    137. "lastHeartbeat" : ISODate("2023-10-23T03:13:32.393Z"),
    138. "lastHeartbeatRecv" : ISODate("2023-10-23T03:13:32.445Z"),
    139. "pingMs" : NumberLong(1),
    140. "lastHeartbeatMessage" : "",
    141. "syncingTo" : "",
    142. "syncSourceHost" : "",
    143. "syncSourceId" : -1,
    144. "infoMessage" : "",
    145. "configVersion" : 2
    146. },
    147. {
    148. "_id" : 3,
    149. "name" : "192.168.122.36:27020",
    150. "health" : 1,
    151. "state" : 7,
    152. "stateStr" : "ARBITER",
    153. "uptime" : 6,
    154. "lastHeartbeat" : ISODate("2023-10-23T03:13:32.405Z"),
    155. "lastHeartbeatRecv" : ISODate("2023-10-23T03:13:32.455Z"),
    156. "pingMs" : NumberLong(4),
    157. "lastHeartbeatMessage" : "",
    158. "syncingTo" : "",
    159. "syncSourceHost" : "",
    160. "syncSourceId" : -1,
    161. "infoMessage" : "",
    162. "configVersion" : 2
    163. }
    164. ],
    165. "ok" : 1,
    166. "$clusterTime" : {
    167. "clusterTime" : Timestamp(1698030806, 1),
    168. "signature" : {
    169. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    170. "keyId" : NumberLong(0)
    171. }
    172. },
    173. "operationTime" : Timestamp(1698030806, 1)
    174. }

    此时修改python中程序(插入的数据),运行结果如下:

    da5eec3d48507bcdbd63921f39fc8e13.png

    3.  删除数据节点
    如果你需要删除一个数据节点,首先,你要确保副本集的健康状态,然后执行如下操作来删除一个Secondary节点。

    rs.remove("IP:PORT");

    执行这个命令后,MongoDB将从副本集中移除该数据节点,副本集会重新进行选举,确保副本集的高可用性

    1. test1:PRIMARY> rs.remove("192.168.122.36:27019")
    2. {
    3. "ok" : 1,
    4. "$clusterTime" : {
    5. "clusterTime" : Timestamp(1698038888, 1),
    6. "signature" : {
    7. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    8. "keyId" : NumberLong(0)
    9. }
    10. },
    11. "operationTime" : Timestamp(1698038888, 1)
    12. }
    13. test1:PRIMARY> rs.status
    14. function() {
    15. return db._adminCommand("replSetGetStatus"); # 选举中
    16. }
    17. test1:PRIMARY> rs.status()
    18. {
    19. "set" : "test1",
    20. "date" : ISODate("2023-10-23T05:28:15.398Z"),
    21. "myState" : 1,
    22. "term" : NumberLong(1),
    23. "syncingTo" : "",
    24. "syncSourceHost" : "",
    25. "syncSourceId" : -1,
    26. "heartbeatIntervalMillis" : NumberLong(2000),
    27. "majorityVoteCount" : 2,
    28. "writeMajorityCount" : 2,
    29. "optimes" : {
    30. "lastCommittedOpTime" : {
    31. "ts" : Timestamp(1698038888, 1),
    32. "t" : NumberLong(1)
    33. },
    34. "lastCommittedWallTime" : ISODate("2023-10-23T05:28:08.335Z"),
    35. "readConcernMajorityOpTime" : {
    36. "ts" : Timestamp(1698038888, 1),
    37. "t" : NumberLong(1)
    38. },
    39. "readConcernMajorityWallTime" : ISODate("2023-10-23T05:28:08.335Z"),
    40. "appliedOpTime" : {
    41. "ts" : Timestamp(1698038888, 1),
    42. "t" : NumberLong(1)
    43. },
    44. "durableOpTime" : {
    45. "ts" : Timestamp(1698038888, 1),
    46. "t" : NumberLong(1)
    47. },
    48. "lastAppliedWallTime" : ISODate("2023-10-23T05:28:08.335Z"),
    49. "lastDurableWallTime" : ISODate("2023-10-23T05:28:08.335Z")
    50. },
    51. "lastStableRecoveryTimestamp" : Timestamp(1698038845, 1),
    52. "lastStableCheckpointTimestamp" : Timestamp(1698038845, 1),
    53. "electionCandidateMetrics" : {
    54. "lastElectionReason" : "electionTimeout",
    55. "lastElectionDate" : ISODate("2023-10-23T02:30:24.838Z"),
    56. "electionTerm" : NumberLong(1),
    57. "lastCommittedOpTimeAtElection" : {
    58. "ts" : Timestamp(0, 0),
    59. "t" : NumberLong(-1)
    60. },
    61. "lastSeenOpTimeAtElection" : {
    62. "ts" : Timestamp(1698028214, 1),
    63. "t" : NumberLong(-1)
    64. },
    65. "numVotesNeeded" : 2,
    66. "priorityAtElection" : 1,
    67. "electionTimeoutMillis" : NumberLong(10000),
    68. "numCatchUpOps" : NumberLong(0),
    69. "newTermStartDate" : ISODate("2023-10-23T02:30:24.912Z"),
    70. "wMajorityWriteAvailabilityDate" : ISODate("2023-10-23T02:30:25.497Z")
    71. },
    72. "members" : [
    73. {
    74. "_id" : 0,
    75. "name" : "192.168.122.36:27017",
    76. "health" : 1,
    77. "state" : 1,
    78. "stateStr" : "PRIMARY",
    79. "uptime" : 10816,
    80. "optime" : {
    81. "ts" : Timestamp(1698038888, 1),
    82. "t" : NumberLong(1)
    83. },
    84. "optimeDate" : ISODate("2023-10-23T05:28:08Z"),
    85. "syncingTo" : "",
    86. "syncSourceHost" : "",
    87. "syncSourceId" : -1,
    88. "infoMessage" : "",
    89. "electionTime" : Timestamp(1698028224, 1),
    90. "electionDate" : ISODate("2023-10-23T02:30:24Z"),
    91. "configVersion" : 3,
    92. "self" : true,
    93. "lastHeartbeatMessage" : ""
    94. },
    95. {
    96. "_id" : 1,
    97. "name" : "192.168.122.36:27018",
    98. "health" : 1,
    99. "state" : 2,
    100. "stateStr" : "SECONDARY",
    101. "uptime" : 10680,
    102. "optime" : {
    103. "ts" : Timestamp(1698038888, 1),
    104. "t" : NumberLong(1)
    105. },
    106. "optimeDurable" : {
    107. "ts" : Timestamp(1698038888, 1),
    108. "t" : NumberLong(1)
    109. },
    110. "optimeDate" : ISODate("2023-10-23T05:28:08Z"),
    111. "optimeDurableDate" : ISODate("2023-10-23T05:28:08Z"),
    112. "lastHeartbeat" : ISODate("2023-10-23T05:28:14.347Z"),
    113. "lastHeartbeatRecv" : ISODate("2023-10-23T05:28:15.388Z"),
    114. "pingMs" : NumberLong(1),
    115. "lastHeartbeatMessage" : "",
    116. "syncingTo" : "",
    117. "syncSourceHost" : "",
    118. "syncSourceId" : -1,
    119. "infoMessage" : "",
    120. "configVersion" : 3
    121. },
    122. {
    123. "_id" : 3,
    124. "name" : "192.168.122.36:27020",
    125. "health" : 1,
    126. "state" : 7,
    127. "stateStr" : "ARBITER",
    128. "uptime" : 8088,
    129. "lastHeartbeat" : ISODate("2023-10-23T05:28:14.342Z"),
    130. "lastHeartbeatRecv" : ISODate("2023-10-23T05:28:14.369Z"),
    131. "pingMs" : NumberLong(0),
    132. "lastHeartbeatMessage" : "",
    133. "syncingTo" : "",
    134. "syncSourceHost" : "",
    135. "syncSourceId" : -1,
    136. "infoMessage" : "",
    137. "configVersion" : 3
    138. }
    139. ],
    140. "ok" : 1,
    141. "$clusterTime" : {
    142. "clusterTime" : Timestamp(1698038888, 1),
    143. "signature" : {
    144. "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    145. "keyId" : NumberLong(0)
    146. }
    147. },
    148. "operationTime" : Timestamp(1698038888, 1)
    149. }

    注意:复制集将会短暂的关闭连接并进入选举,选举出一个新的主节点。接口将会自动重连。接口可能将会报错 DBClientCursor::init call() failed 。

    9ca11f2ecdc7c55235c38025419219d9.png

    往期精彩回顾

    1.  MySQL高可用之MHA集群部署

    2.  mysql8.0新增用户及加密规则修改的那些事

    3.  比hive快10倍的大数据查询利器-- presto

    4.  监控利器出鞘:Prometheus+Grafana监控MySQL、Redis数据库

    5.  PostgreSQL主从复制--物理复制

    6.  MySQL传统点位复制在线转为GTID模式复制

    7.  MySQL敏感数据加密及解密

    8.  MySQL数据备份及还原(一)

    9.  MySQL数据备份及还原(二)

    310a4d503c1ea9c406914e651413fcd0.png

    扫码关注     

    2a01b9f48c109eafa9f05c96863bcecc.jpeg

    c252dc830e264d24960c7280c3c45d22.png

    5534f6a86bd4f608af8afb5c389b0f13.png

  • 相关阅读:
    LeetCode面向运气之Javascript—第20题-有效的括号-95.97%
    剪映软件专业版的操作与使用,电脑版与手机版APP同步讲解
    图论应用——拓扑排序
    C语言笔记-21-Linux基础-信号
    香橙派、树莓派、核桃派、鲁班猫安装jupyter notebook【ubuntu、Debian开发板操作类似】
    Helm & Kubernetes Offline Deploy Rancher v2.7.5 Demo (helm 离线部署 rancher 实践)
    SpringMVC 始+五种数据提交的方法
    Python练习题:找到列表中消失的所有数字
    华为云云服务器评测|详解 Nacos 安装部署
    信息学奥赛一本通:2033:【例4.19】阶乘之和
  • 原文地址:https://blog.csdn.net/gjc592/article/details/134025344