전용 서버에 지역화된 멀티스레딩을 추가하는 Fork of Paper.
Folia 그룹은 로드된 청크 근처에 모여 "독립 영역"을 형성합니다. Folia가 근처 청크를 그룹화하는 방법에 대한 정확한 세부 정보는 PaperMC 설명서를 참조하세요. 각 독립 지역에는 일반 Minecraft 틱레이트(20TPS)로 틱되는 자체 틱 루프가 있습니다. 틱 루프는 스레드 풀에서 병렬로 실행됩니다. 각 영역에는 전체 틱 루프를 실행하는 자체 "메인 스레드"가 있으므로 더 이상 메인 스레드가 없습니다.
분산된 플레이어가 많은 서버의 경우 Folia는 분산된 여러 영역을 생성하고 구성 가능한 크기의 스레드 풀에서 모든 영역을 병렬로 선택합니다. 따라서 Folia는 이와 같은 서버에 맞게 확장성이 뛰어납니다.
Folia는 자체 프로젝트이기도 하며 가까운 미래에는 Paper에 병합되지 않을 것입니다.
더 자세하지만 추상적인 개요: 프로젝트 개요.
Skyblock이나 SMP처럼 자연스럽게 플레이어를 분산시키는 서버 유형은 Folia의 이점을 가장 많이 누릴 것입니다. 서버에는 상당한 규모의 플레이어 수가 있어야 합니다.
이상적으로는 최소 16개 코어 (스레드 아님)입니다.
첫째, 필요한 청크 시스템 작업자 스레드 수가 크게 줄어들도록 월드를 미리 생성하는 것이 좋습니다.
다음은 최대 330명의 플레이어가 있었던 테스트 서버에서 Folia가 출시되기 전에 수행한 테스트를 기반으로 한 대략적인 추정치입니다. 따라서 정확하지 않으며 추가 조정이 필요합니다. 시작점으로 삼으세요.
머신에서 사용 가능한 총 코어 수를 고려해야 합니다. 그런 다음 다음에 대한 스레드를 할당합니다.
-XX:ConcGCThreads=n
플래그를 통해 이루어집니다. 이 플래그를 -XX:ParallelGCThreads=n
과 혼동하지 마십시오. 병렬 GC 스레드는 애플리케이션이 GC에 의해 일시 중지될 때만 실행되므로 이를 고려하면 안 됩니다.할당이 모두 완료되면 80% 할당(할당된 총 스레드 < 사용 가능한 CPU의 80%)까지 시스템의 나머지 코어를 틱스레드(전역 구성, threaded-regions.threads에서)에 할당할 수 있습니다.
코어의 80% 이상을 할당하지 말아야 하는 이유는 플러그인이나 심지어 서버가 구성하거나 예측할 수 없는 추가 스레드를 사용할 수 있다는 사실 때문입니다.
또한 위의 내용은 모두 플레이어 수를 기준으로 한 대략적인 추측이지만 스레드 할당이 이상적이지 않을 가능성이 매우 높으므로 표시되는 스레드 사용량에 따라 조정해야 합니다.
더 이상 메인 스레드가 없습니다. 존재하는 모든 단일 플러그인이 Folia에서 작동하려면 일정 수준의 수정이 필요할 것으로 예상됩니다. 또한 모든 종류 의 멀티스레딩은 플러그인 보유 데이터에 경쟁 조건을 발생시킬 수 있으므로 반드시 변경해야 할 사항이 있습니다.
따라서 호환성에 대한 기대치를 0으로 설정하세요.
현재 메인 스레드에 의존하는 API가 많이 있습니다. 나는 기본적으로 Paper와 호환되는 플러그인이 Folia와 호환될 것으로 기대합니다. 그러나 Folia 플러그인이 Paper와 호환되도록 하는 API를 추가할 계획이 있습니다.
예를 들어 Bukkit 스케줄러가 있습니다. Bukkit Scheduler는 본질적으로 단일 메인 스레드에 의존합니다. Folia의 RegionScheduler와 Folia의 EntityScheduler를 사용하면 위치나 엔터티를 "소유"하는 모든 지역의 "다음 틱"에 대한 작업 일정을 설정할 수 있습니다. 이는 메인 스레드에 대한 일정을 제외하고 일반 Paper에서 구현될 수 있습니다. 두 경우 모두 작업 실행은 위치나 엔터티를 "소유"하는 스레드에서 발생합니다. 현재 Paper(단일 스레드)는 모든 세계의 모든 청크를 포함하는 하나의 거대한 "영역"으로 볼 수 있으므로 이 개념은 일반적으로 적용됩니다.
이 API를 Paper 자체에 직접 추가할지, Paperlib에 추가할지 아직 결정되지 않았습니다.
첫째, Folia는 많은 플러그인을 중단시킵니다. 사용자가 어떤 플러그인이 작동하는지 파악하는 데 도움을 주기 위해 작성자가 Folia와 함께 작동하도록 명시적으로 표시한 플러그인만 로드됩니다. 플러그인의plugin.yml에 "folia-supported: true"를 배치하면 플러그인 작성자는 해당 플러그인을 지역화된 멀티스레딩과 호환되는 것으로 표시할 수 있습니다.
또 다른 중요한 규칙은 영역이 동시에 틱되는 것이 아니라 병렬 로 틱된다는 것입니다. 그들은 데이터를 공유하지 않으며, 데이터 공유를 기대하지 않으며, 데이터 공유로 인해 데이터 손상이 발생 합니다 . 어떤 상황에서도 한 지역에서 실행되는 코드는 다른 지역에 있는 데이터에 액세스하거나 수정할 수 없습니다. 이름에 멀티스레딩이 있다고 해서 모든 것이 이제 스레드로부터 안전하다는 의미는 아닙니다. 실제로 이를 실현하기 위해 스레드로부터 안전하게 만들어진 항목은 몇 가지뿐입니다. 시간이 지남에 따라 성능 저하가 발생 하더라도 스레드 컨텍스트 확인 수는 계속 증가할 것입니다. 버그가 많은 서버 플랫폼을 사용하거나 개발하는 사람은 아무도 없으며 이를 방지하고 찾는 유일한 방법입니다. 버그는 잘못된 액세스의 소스에서 잘못된 액세스가 실패 하도록 만드는 것입니다.
이는 Folia 호환 플러그인이 해당 코드가 올바른 스레드 컨텍스트에서 실행되도록 보장하기 위해 RegionScheduler 및 EntityScheduler와 같은 API를 활용해야 함을 의미합니다.
일반적으로 한 지역이 이벤트 소스로부터 약 8개의 청크에 있는 청크 데이터를 소유한다고 가정하는 것이 안전합니다(예: 플레이어가 블록을 깨고 해당 블록 주변의 8개 청크에 액세스할 수 있음). 그러나 이것이 보장되는 것은 아닙니다. 플러그인은 올바른 동작을 보장하기 위해 곧 출시될 스레드 검사 API를 활용해야 합니다.
스레드 안전성에 대한 유일한 보장은 단일 영역이 특정 청크의 데이터를 소유한다는 사실에서 비롯됩니다. 그리고 해당 영역이 작동 중이면 해당 데이터에 대한 전체 액세스 권한을 갖습니다. 이 데이터는 구체적으로 엔터티/청크/poi 데이터이며 어떤 플러그인 데이터와도 전혀 관련이 없습니다.
플러그인이 자체 데이터 또는 다른 플러그인(이벤트/명령/등)을 저장/액세스하는 데이터에는 일반적인 멀티스레딩 규칙이 적용됩니다. 영역이 병렬 로 틱되기 때문에 병렬 로 호출됩니다(교착 상태 문제가 발생하고 성능이 저하되므로 동기 방식으로 호출할 수 없습니다). 이 문제를 해결하는 쉬운 방법은 없습니다. 이는 전적으로 액세스되는 데이터에 따라 다릅니다. 때로는 동시 컬렉션(예: ConcurrentHashMap)으로 충분할 수 있으며, 부주의하게 사용된 동시 컬렉션은 스레딩 문제만 숨겨 디버깅이 거의 불가능해지는 경우가 많습니다.
API 추가 사항을 제대로 이해하려면 프로젝트 개요를 읽어보세요.
API 추가 사항을 제대로 이해하려면 프로젝트 개요를 읽어보세요.
일반적인 경험 법칙:
엔터티/플레이어에 대한 명령은 엔터티/플레이어를 소유한 지역에서 호출됩니다. 콘솔 명령은 글로벌 리전에서 실행됩니다.
단일 엔터티(예: 플레이어 중단/블록 배치)와 관련된 이벤트는 지역 소유 엔터티에서 호출됩니다. 엔터티에 대한 작업(예: 엔터티 피해)과 관련된 이벤트는 대상 엔터티를 소유한 지역에서 호출됩니다.
이벤트에 대한 async 수정자는 더 이상 사용되지 않습니다. 더 이상 기본 스레드가 없더라도 지역 또는 전역 지역에서 발생하는 모든 이벤트는 동기로 간주됩니다.
< repository >
< id >papermc</ id >
< url >https://repo.papermc.io/repository/maven-public/</ url >
</ repository >
< dependency >
< groupId >dev.folia</ groupId >
< artifactId >folia-api</ artifactId >
< version >1.20.1-R0.1-SNAPSHOT</ version >
< scope >provided</ scope >
</ dependency >
PATCHES-LICENSE 파일은 달리 명시되지 않는 한 ./patches
및 해당 하위 디렉터리에 있는 API 및 서버 패치에 대한 라이선스를 설명합니다.
포크는 여기에 있는 PaperMC의 포크 예제를 기반으로 합니다. 따라서 이 프로젝트에는 수정 사항이 포함되어 있습니다. 수정된 파일의 라이센스 정보는 저장소를 참조하세요.