|
48 | 48 | import org.apache.pulsar.broker.storage.ManagedLedgerStorageClass; |
49 | 49 | import org.apache.pulsar.common.policies.data.EnsemblePlacementPolicyConfig; |
50 | 50 | import org.apache.pulsar.common.stats.CacheMetricsCollector; |
| 51 | +import org.apache.pulsar.common.util.DirectMemoryUtils; |
51 | 52 | import org.apache.pulsar.metadata.api.extended.MetadataStoreExtended; |
52 | 53 |
|
53 | 54 | @CustomLog |
@@ -90,18 +91,34 @@ public void initialize(ServiceConfiguration conf, MetadataStoreExtended metadata |
90 | 91 | ); |
91 | 92 | } |
92 | 93 | managedLedgerFactoryConfig.setCopyEntriesInCache(conf.isManagedLedgerCacheCopyEntries()); |
93 | | - long managedLedgerMaxReadsInFlightSizeBytes = conf.getManagedLedgerMaxReadsInFlightSizeInMB() * 1024L * 1024L; |
94 | | - if (managedLedgerMaxReadsInFlightSizeBytes > 0 && conf.getDispatcherMaxReadSizeBytes() > 0 |
95 | | - && managedLedgerMaxReadsInFlightSizeBytes < conf.getDispatcherMaxReadSizeBytes()) { |
96 | | - log.warn() |
97 | | - .attr("managedLedgerMaxReadsInFlightSizeInMB", conf.getManagedLedgerMaxReadsInFlightSizeInMB()) |
98 | | - .attr("dispatcherMaxReadSizeBytes", conf.getDispatcherMaxReadSizeBytes()) |
99 | | - .attr("minManagedLedgerMaxReadsInFlightSizeInMB", |
100 | | - (conf.getDispatcherMaxReadSizeBytes() / (1024L * 1024L)) + 1) |
101 | | - .log("Invalid configuration:" |
102 | | - + " managedLedgerMaxReadsInFlightSizeInMB in bytes" |
103 | | - + " should be greater than" |
104 | | - + " dispatcherMaxReadSizeBytes"); |
| 94 | + Long managedLedgerMaxReadsInFlightSizeInMB = conf.getManagedLedgerMaxReadsInFlightSizeInMB(); |
| 95 | + // A single dispatcher read can retain up to dispatcherMaxReadSizeBytes bytes. The in-flight reads |
| 96 | + // limit must be at least this size, otherwise the limiter can block the completion of a single read. |
| 97 | + long dispatcherMaxReadSizeBytes = conf.getDispatcherMaxReadSizeBytes(); |
| 98 | + final long managedLedgerMaxReadsInFlightSizeBytes; |
| 99 | + if (managedLedgerMaxReadsInFlightSizeInMB == null) { |
| 100 | + // When unset, default to 15% of the available JVM direct memory, but never below the maximum |
| 101 | + // size of a single read (dispatcherMaxReadSizeBytes) so that the limiter can never block the |
| 102 | + // completion of one read. |
| 103 | + long fractionOfDirectMemory = (long) (0.15d * DirectMemoryUtils.jvmMaxDirectMemory()); |
| 104 | + managedLedgerMaxReadsInFlightSizeBytes = Math.max(fractionOfDirectMemory, dispatcherMaxReadSizeBytes); |
| 105 | + } else { |
| 106 | + // An explicit 0 disables the feature; an explicit value > 0 is used as-is. |
| 107 | + managedLedgerMaxReadsInFlightSizeBytes = managedLedgerMaxReadsInFlightSizeInMB * 1024L * 1024L; |
| 108 | + // Warn when the feature is enabled but manually configured below the size of a single read, since |
| 109 | + // the limiter would then be unable to admit one read. Disabled (0) is ignored. |
| 110 | + if (managedLedgerMaxReadsInFlightSizeBytes > 0 && dispatcherMaxReadSizeBytes > 0 |
| 111 | + && managedLedgerMaxReadsInFlightSizeBytes < dispatcherMaxReadSizeBytes) { |
| 112 | + log.warn() |
| 113 | + .attr("managedLedgerMaxReadsInFlightSizeInMB", managedLedgerMaxReadsInFlightSizeInMB) |
| 114 | + .attr("dispatcherMaxReadSizeBytes", dispatcherMaxReadSizeBytes) |
| 115 | + .attr("minManagedLedgerMaxReadsInFlightSizeInMB", |
| 116 | + (dispatcherMaxReadSizeBytes + (1024L * 1024L) - 1) / (1024L * 1024L)) |
| 117 | + .log("Invalid configuration:" |
| 118 | + + " managedLedgerMaxReadsInFlightSizeInMB in bytes should be greater than or" |
| 119 | + + " equal to dispatcherMaxReadSizeBytes, otherwise the in-flight reads limiter" |
| 120 | + + " can block the completion of a single read."); |
| 121 | + } |
105 | 122 | } |
106 | 123 | managedLedgerFactoryConfig.setManagedLedgerMaxReadsInFlightSize(managedLedgerMaxReadsInFlightSizeBytes); |
107 | 124 | managedLedgerFactoryConfig.setManagedLedgerMaxReadsInFlightPermitsAcquireTimeoutMillis( |
|
0 commit comments