[ 
https://issues.apache.org/jira/browse/HBASE-13686?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14543923#comment-14543923
 ] 

Guanghao Zhang commented on HBASE-13686:
----------------------------------------

Think this scenario, we have one RateLimter  which limit=10000 per seconds and 
the client want to have about 6000 resources/sec.
{code}
                RateLimiter limiter = new RateLimiter();
                limiter.set(10000, TimeUnit.SECONDS); // set 10000 resources/sec
                limiter.consume(10000); // initialize the limiter to have no 
available resources

                long lastTs = System.currentTimeMillis();
                while (true) {
                        // client want get  about 6000 resources per seconds
                        Thread.sleep(1);
                        for (int i = 0; i < 6; i++) {
                                long now = System.currentTimeMillis();
                                boolean canExecute = limiter.canExecute(now, 
lastTs);
                                if (!canExecute) {
                                        System.out.println("rejected");
                                        Thread.sleep(limiter.waitInterval());
                                }
                                limiter.consume();
                                lastTs = now;
                        }
                }
{/code}
Test the above code, we will get a lot rejected in the console. Or you can add 
the assertTrue(canExecute). But the real is canExecute maybe false.
The key point is "lastTs". The code update lastTs every consume, but don't 
refill the limiter. So a 10000 resources/sec limiter will reject the 6000 
resources/sec request.
You maybe confused about why the code update lastTs every consume. See 
TimeBasedLimiter. When grabQuota, it update lastTs(writeLastTs or ReadLastTs).  
 

> Fail to limit rate in RateLimiter
> ---------------------------------
>
>                 Key: HBASE-13686
>                 URL: https://issues.apache.org/jira/browse/HBASE-13686
>             Project: HBase
>          Issue Type: Bug
>    Affects Versions: 2.0.0, 1.1.0
>            Reporter: Guanghao Zhang
>            Priority: Minor
>
> While using the patch in HBASE-11598 , I found that RateLimiter can't to 
> limit the rate right.
> {code} 
>  /**
>    * given the time interval, are there enough available resources to allow 
> execution?
>    * @param now the current timestamp
>    * @param lastTs the timestamp of the last update
>    * @param amount the number of required resources
>    * @return true if there are enough available resources, otherwise false
>    */
>   public synchronized boolean canExecute(final long now, final long lastTs, 
> final long amount) {
>     return avail >= amount ? true : refill(now, lastTs) >= amount;
>   }
> {code}
> When avail >= amount, avail can't be refill. But in the next time to call 
> canExecute, lastTs maybe update. So avail will waste some time to refill. 
> Even we use smaller rate than the limit, the canExecute will return false. 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to