Chia sẻ kiến thức IT và đời sống – Sharing IT Knowledge & Life Insights

Hiển thị các bài đăng có nhãn Backend. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn Backend. Hiển thị tất cả bài đăng

Thứ Bảy, 31 tháng 10, 2026

Redis A–Z, Java & TTL: Overview

A concise guide to Redis: what it is, how to deploy it, how it persists data, when you need it, how to use it in Java, and how TTL works. Every code block is labeled as one of the following types: a Redis command, Java code, or a configuration file.

Vietnamese version 

Redis at a glance

Redis is a fast in-memory data store commonly used alongside a primary database such as PostgreSQL or MySQL. In Java/Spring applications, its most common jobs are caching, shared sessions, distributed coordination, rate limiting, and real-time counters.

Highlights

  • What Redis is and how its deployment models differ.
  • How RDB and AOF protect data when Redis restarts.
  • When Redis is useful, and when a normal database is enough.
  • How Java/Spring code maps to Redis commands.
  • How TTL, expiration, and eviction work in practice.

Suggested reading order: read sections 1–4 first to understand Redis; then choose the Java use case in section 5 that matches your application; finally read section 6 to understand expiration and memory management.

How to read this article

Redis articles mix several "languages" in one page, which is confusing at first. Here is how each block is labeled:

LabelWhat it isWhere you use it
REDIS COMMANDA command you type directly into Redis (like SQL for a SQL database). Dark background.Terminal, running redis-cli
JAVA CODEJava (Spring Boot) code that talks to Redis. Light background.Your application source code
CONFIG / XMLSettings files, not code that runs by itself.redis.conf, application.properties, pom.xml
LUA SCRIPTA small script that runs inside Redis, so several steps execute as one unit.Sent to Redis with the EVAL command

Small things that look strange but are simple:

  • Redis blocks: the > at the start of a line is the redis-cli prompt. You type what comes after it. Lines without > are Redis's reply (for example (integer) 1 means "the answer is the number 1", and (nil) means "nothing / not found").
  • Command names are case-insensitive (set = SET), but by convention they are written in UPPERCASE so they stand out from keys and values.
  • key and value in a command pattern are placeholders. You replace them with your own names.
  • Colons in key names such as rate:user42 or lock:product:7 are only a naming habit to group keys (like folders). Redis does not treat : as special.
  • ... inside a sentence means "and other options / and others". It is not part of the syntax.
  • // in Java code starts a comment. Redis config files use # for comments.
  • Unknown word? Jump to the Glossary (section 8).

1. What is Redis?

Redis (Remote Dictionary Server) is a NoSQL key-value database that keeps data mainly in RAM, so reads and writes are extremely fast (sub-millisecond, meaning less than 1/1000 of a second).

  • It is a real database: you can insert, update, delete, and query data like any other DB. The difference is that you use commands (SET, GET, HSET, ZADD...) instead of SQL.
  • Data types: String, Hash, List, Set, Sorted Set, Stream, Bitmap, HyperLogLog, Geo.
  • Built-in persistence, replication, transactions, pub/sub, and TTL.

A first taste. SET stores a value under a key, GET reads it back:

REDIS COMMAND · type in redis-cli
> SET user:1:name "Linh"
OK
> GET user:1:name
"Linh"
> GET user:999:name
(nil)

The last reply is (nil) because that key does not exist.

2. Deployment Models

ModelDescriptionWhen to use
StandaloneA single instanceSmall/medium apps that tolerate short downtime
Master-ReplicaOne master for writes, replicas (read-only copies) for readsNeed more read capacity and a backup copy
SentinelMaster-Replica plus monitoring and automatic failover (if the master dies, a replica is promoted to master automatically)Need high availability (HA), meaning the system stays up when one server fails; data fits on one machine
ClusterData is sharded (split into pieces) across 16,384 hash slots, each shard with replicasData exceeds one machine's RAM; need to scale reads and writes
Rule of thumb: start with Standalone, move to Sentinel for HA, and use Cluster when you need to scale data or writes.

3. Persistence: RDB vs AOF

Persistence means saving RAM data to disk, so it survives a restart.

RDB (snapshot) takes periodic point-in-time dumps of the whole dataset.

  • Pros: compact file, fast restore, low performance impact.
  • Cons: a crash loses everything since the last snapshot.

AOF (Append Only File) logs every write command.

  • Pros: much more durable. With appendfsync everysec you lose at most ~1 second of data.
  • Cons: larger files and slower restore (mitigated by AOF rewrite, which compacts the log).

Why AOF if we already have RDB? RDB is only a periodic snapshot, so a crash between two snapshots loses data. AOF records continuously and minimizes that loss.

What should you choose?

  • Pure cache: disable persistence, or use RDB only.
  • Important data: enable RDB + AOF (everysec). RDB gives fast backups and restores, AOF gives durability. On restart, Redis prefers the AOF because it is more complete.

Note that appendfsync everysec is not a command you type. It is a setting in the Redis config file:

CONFIG · redis.conf
# RDB: take a snapshot if at least 1 key changed within 900 seconds
save 900 1

# AOF: turn it on, and flush the log to disk once per second
appendonly yes
appendfsync everysec

fsync means "force the data to be physically written to disk". everysec = do it every second (a good balance of safety and speed).

4. When Do You Actually Need Redis?

Not every application needs Redis. Adding it means more infrastructure, more operational cost, and the risk of cache inconsistency (the cache and the database showing different data).

Use Redis when:

  • The workload is read-heavy and the main DB is overloaded (caching: keeping a fast copy of frequently read data).
  • You need very fast responses: leaderboards, view counters, rate limiting (limiting how many requests a user may make).
  • Multiple app servers must share sessions (the "this user is logged in" information).
  • You need distributed locks (a lock shared across several servers), lightweight queues, or pub/sub (publish/subscribe messaging).
  • You store short-lived data: OTPs (One-Time Passwords, such as the 6-digit code sent by SMS) and tokens (temporary proof of identity, such as a password-reset link code).

You probably don't need it when:

  • It is an internal app with few users and the DB handles the load fine.
  • You haven't optimized your indexes and queries yet. Do that first.
  • You need strict ACID guarantees (reliable transactions) and complex relations. Redis does not replace an RDBMS (relational database such as MySQL or PostgreSQL).
  • Budget or ops skills are limited: RAM costs more than disk, and Sentinel/Cluster need someone who can run them.
Scale hint: consider Redis when DB latency (response time) starts rising, repeated reads reach thousands of requests per second, or multiple app instances need shared state.

5. Redis in Java

Common clients (Java libraries that connect to Redis):

  • Spring Data Redis (RedisTemplate, StringRedisTemplate): the most popular choice in Spring Boot.
  • Lettuce (Spring Boot default, async/non-blocking) and Jedis (simple, synchronous).
  • Redisson: ready-made distributed locks, semaphores, rate limiters, and collections.

The key idea: Java methods are just translated into Redis commands

When your Java code calls redisTemplate.opsForValue().increment(key), the library sends the Redis command INCR key to the server. Same thing, different "language". Keep this table handy, because the rest of the article uses both forms:

Java code (RedisTemplate)Redis command it sendsMeaning
opsForValue().set(k, v)SET k vStore a value
opsForValue().set(k, v, 60, TimeUnit.SECONDS)SET k v EX 60Store a value that expires in 60 s
opsForValue().get(k)GET kRead a value
opsForValue().increment(k)INCR kAdd 1 to a number
expire(k, 1, TimeUnit.MINUTES)EXPIRE k 60Set a lifespan on an existing key
opsForZSet().incrementScore(k, m, 50)ZINCRBY k 50 mAdd 50 points to member m
opsForZSet().reverseRangeWithScores(k, 0, 9)ZREVRANGE k 0 9 WITHSCORESTop 10, highest first
opsForZSet().reverseRank(k, m)ZREVRANK k mRank of member m

5.1 Caching with @Cacheable

Idea: before running an expensive database query, check Redis first. If the answer is there (a cache hit), return it. If not (a cache miss), query the DB and store the result in Redis for next time.

In Spring you do this with annotations. An annotation is a label starting with @ that you put above a method to add behavior without writing the logic yourself.

JAVA CODE · Spring Boot
@Cacheable(value = "products", key = "#id")   // return cached value, or run method and store it
public Product getProduct(Long id) { return repo.findById(id).orElseThrow(); }

@CachePut(value = "products", key = "#p.id")  // always run and update the cache
public Product update(Product p) { return repo.save(p); }

@CacheEvict(value = "products", key = "#id")  // remove from cache when data changes
public void delete(Long id) { repo.deleteById(id); }

Reading the annotation parameters:

  • value = "products": the name of the cache (think of it as a folder name).
  • key = "#id": the cache key. #id is a Spring expression (SpEL) meaning "use this method's parameter called id". #p.id means "the id field of parameter p".
  • In Redis, the entry ends up under a key like products::5 (cache name + :: + key). You can inspect it with a Redis command:
REDIS COMMAND · type in redis-cli
> KEYS products::*
1) "products::5"
> TTL products::5
(integer) 540

KEYS pattern lists keys matching a pattern (* = anything). Use it only for debugging on a small dev instance, because it is slow on big databases.

Notes:

  • When DB data changes, you must @CacheEvict or @CachePut, or readers will see stale (outdated) data.
  • Caching works through a proxy (Spring wraps your class with a helper object), so calling a method from within the same class bypasses the cache.
  • To prevent cache penetration (repeated queries for keys that don't exist, which always fall through to the DB), cache null values with a short TTL.

5.2 Sessions with Spring Session

Problem: behind a load balancer (a device that spreads requests across several servers), in-memory sessions are tied to one server, so users get logged out when a request lands on another.
Solution: store sessions centrally in Redis.

Step 1: add the library to your Maven build file.

XML · pom.xml (Maven)
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

Step 2: tell Spring where Redis is.

CONFIG · application.properties
spring.data.redis.host=localhost
spring.data.redis.port=6379

(On Spring Boot 2.x the prefix is spring.redis.* instead of spring.data.redis.*.)

That's all. Spring Boot swaps HttpSession for a Redis-backed one. Your session.setAttribute(...) code stays the same. Stored objects must be serializable (convertible to bytes so they can be saved). Sessions appear in Redis as keys starting with spring:session:, with a TTL equal to the session timeout. If you use stateless JWT (a signed token the client carries, so the server stores nothing), you usually don't need this.

5.3 Distributed Locks with Redisson

Problem: Java's synchronized only locks within a single JVM (one running Java program). Across multiple instances, two requests can still process the same resource at once (e.g., both decrementing the same stock).

Idea: use a key in Redis as the lock. Whoever creates the key first owns the lock. Under the hood, the simplest version is this Redis command:

REDIS COMMAND · type in redis-cli
> SET lock:product:7 server-A NX PX 10000
OK
> SET lock:product:7 server-B NX PX 10000
(nil)
  • NX = "only set if the key does Not eXist". The first caller gets OK (lock acquired). The second gets (nil) (lock already taken).
  • PX 10000 = expire after 10,000 milliseconds (10 s), so a crashed server cannot hold the lock forever.
  • server-A is the owner id, so only the owner releases it.

Writing this safely by hand is tricky, so the Java library Redisson does it for you:

JAVA CODE · Redisson
RLock lock = redisson.getLock("lock:product:" + productId);
try {
    // wait up to 5s to acquire, auto-release after 10s
    if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
        // decrement stock, create order...
    } else {
        throw new RuntimeException("System busy, try again later");
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
} finally {
    if (lock.isHeldByCurrentThread()) lock.unlock();
}
  • tryLock(5, 10, SECONDS): wait up to 5 s for someone else to release; once you get it, it auto-expires after 10 s (the "lease time").
  • finally { ... }: this block always runs, even after an error, so the lock is always released.
  • isHeldByCurrentThread(): only unlock if you still own it (it may have already expired).
  • InterruptedException handling: standard Java housekeeping when a waiting thread is interrupted.

Why Redisson over a hand-rolled SET NX: it has a watchdog (a background task, which by default renews the lock every ~10 s with a 30 s lease) that extends the lock while work is still running (only when you do not pass a lease time), and it supports reentrancy (the same thread can lock twice), fair locks, read-write locks, and semaphores.

Notes: always set an expiry to avoid deadlocks if a server dies, and only unlock a lock you hold. For critical business rules, add a DB-level safeguard (unique constraint or optimistic locking) as the last line of defense.

5.4 Rate Limiting

Rate limiting = restricting how many requests one user may send in a period of time, e.g. "max 100 requests per minute". It protects your API from abuse and overload.

What does "window" mean?

The window is simply the length of time over which you count. For "100 requests per minute", the window is 1 minute. A fixed window means the time is cut into fixed blocks (12:00:00–12:00:59, then 12:01:00–12:01:59, ...) and the counter starts again from 0 at each new block.

The Redis commands behind it

The limiter uses two commands: INCR (add 1 to a counter; creates it at 1 if missing) and EXPIRE (delete the key automatically after N seconds). Here is one user's first requests:

REDIS COMMAND · type in redis-cli
> INCR rate:user42
(integer) 1
> EXPIRE rate:user42 60
(integer) 1
> INCR rate:user42
(integer) 2
> TTL rate:user42
(integer) 52
  1. First request: counter becomes 1. Because it is the first, we also start the 60-second window with EXPIRE.
  2. Next requests: counter goes 2, 3, 4... (we do not call EXPIRE again, or the window would keep sliding forward).
  3. After 60 seconds the key disappears, so the next INCR starts again at 1: a new window.
  4. If the counter goes above 100, we reject the request.

The same logic in Java

JAVA CODE · Spring Data Redis
public boolean allow(String userId) {
    String key = "rate:" + userId;                              // e.g. "rate:user42"
    Long count = redisTemplate.opsForValue().increment(key);    // = INCR rate:user42
    if (count == 1) {                                           // first request of this window
        redisTemplate.expire(key, 1, TimeUnit.MINUTES);         // = EXPIRE rate:user42 60
    }
    return count <= 100;   // true = allowed, false = over the limit (max 100 requests/minute)
}

If it returns false, respond with HTTP 429 Too Many Requests (the standard status code meaning "slow down").

Notes:

  • Burst at the boundary. A fixed window resets abruptly. A user can send 100 requests at 12:00:59 and another 100 at 12:01:00, which is 200 requests in 2 seconds while still "within the limit". For smoother behavior use a Sliding Window (the window moves with time; implemented with a Sorted Set) or a Token Bucket (you spend tokens that refill at a steady rate).
  • Not atomic. INCR and EXPIRE are two separate commands. If the app crashes between them, the key never expires and the user is blocked forever. Atomic means "all steps happen as one indivisible unit". The fix is to combine them in a Lua script, which Redis runs without interruption:
LUA SCRIPT · runs inside Redis
local count = redis.call('INCR', KEYS[1])
if count == 1 then
  redis.call('EXPIRE', KEYS[1], ARGV[1])
end
return count

Run it with the EVAL command. KEYS[1] and ARGV[1] are the values you pass in (the key name, and the window length in seconds):

REDIS COMMAND · type in redis-cli
> EVAL "local c = redis.call('INCR', KEYS[1]) if c == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]) end return c" 1 rate:user42 60
(integer) 1

Here 1 after the script means "I am passing 1 key", then come the key (rate:user42) and the extra argument (60).

  • Redisson offers RRateLimiter out of the box, so you write no counting logic yourself:
JAVA CODE · Redisson
RRateLimiter limiter = redisson.getRateLimiter("api:" + userId);
limiter.trySetRate(RateType.OVERALL, 100, 1, RateIntervalUnit.MINUTES);  // 100 permits per 1 minute
if (limiter.tryAcquire(1)) { /* allowed: we took 1 permit */ }

RateType.OVERALL means the limit is shared by all clients using this limiter (PER_CLIENT would give each client its own limit). A "permit" is one allowed request.

5.5 Leaderboards with Sorted Sets

A Sorted Set (ZSET) is a collection where every member has a score, and Redis keeps the members ordered by score automatically. Adding, updating, and fetching the top N are all O(log N). In plain words: even with 1,000,000 members, Redis needs only about 20 steps, far cheaper than running ORDER BY score DESC on a large SQL table.

All Sorted Set commands start with the letter Z (that is how you recognize them). REV in a name means "reverse order" (highest first).

Redis commandPurpose
ZADD / ZINCRBYAdd a member (with a score), or increment its score (INCR + BY)
ZREVRANGEGet the top N (highest first). Range = positions, so 0 9 means the 1st to the 10th
ZREVRANKGet a member's rank (0 = first place)
ZSCOREGet a member's score

Redis commands in action:

REDIS COMMAND · type in redis-cli
> ZINCRBY leaderboard:game1 50 alice
"50"
> ZINCRBY leaderboard:game1 80 bob
"80"
> ZREVRANGE leaderboard:game1 0 9 WITHSCORES
1) "bob"
2) "80"
3) "alice"
4) "50"
> ZREVRANK leaderboard:game1 alice
(integer) 1
> ZSCORE leaderboard:game1 bob
"80"

The same thing from Java (compare with the translation table above):

JAVA CODE · Spring Data Redis
redis.opsForZSet().incrementScore("leaderboard:game1", userId, points);  // add points
redis.opsForZSet().reverseRangeWithScores("leaderboard:game1", 0, 9);    // top 10
redis.opsForZSet().reverseRank("leaderboard:game1", userId);             // rank (0-based)

For daily or weekly boards, put the date in the key (leaderboard:2026-10-31) and attach a TTL (e.g. EXPIRE leaderboard:2026-10-31 604800 = delete after 7 days). Ties: members with equal scores are ordered alphabetically by name. To favor "who reached the score first", encode the timestamp in the score's decimal part (earlier time = slightly larger decimal), so the earlier player ranks higher.

6. TTL: Time To Live

TTL is a key's lifespan. When it runs out, Redis deletes the key automatically. It is the main tool that keeps a cache from growing forever and stale data from living indefinitely.

6.1 Common commands

Redis commandMeaning
SET key value EX 300Set a value with a TTL of 300 seconds. EX = seconds; PX = milliseconds (1000 ms = 1 s)
EXPIRE key 60 / PEXPIRE key 1500Set a TTL on an existing key (seconds / milliseconds)
TTL key / PTTL keyShow remaining time (seconds / milliseconds)
PERSIST keyRemove the TTL so the key lives forever

Tip: a leading P in a Redis command always means milliseconds (PEXPIRE, PTTL, and the PX option).

TTL returns -1 if the key exists but has no expiry, and -2 if the key does not exist (it never existed, or it already expired).

REDIS COMMAND · example: a 5-minute OTP
> SET otp:user42 123456 EX 300
OK
> TTL otp:user42
(integer) 297
> GET otp:user42
"123456"

(5 minutes later)
> GET otp:user42
(nil)
> TTL otp:user42
(integer) -2

6.2 Common pitfalls

  • A plain SET on an existing key clears its TTL. Use SET ... KEEPTTL to keep it (here ... stands for your key and value).
  • Reading a key (GET) does not refresh its TTL. For sliding expiration (the lifespan restarts every time the key is used, as with sessions), call EXPIRE again or use GETEX (read and set a new TTL in one command).
  • TTL applies to the whole key, not to individual elements inside a Hash, List, or Set.
REDIS COMMAND · pitfalls in action
> SET session:1 abc EX 1800
OK
> SET session:1 xyz
OK
> TTL session:1
(integer) -1

> SET session:1 xyz KEEPTTL
OK
> GETEX session:1 EX 1800
"xyz"

After the second SET, the TTL is -1 (the expiry was wiped). GETEX session:1 EX 1800 returns the value and restarts the 30-minute lifespan.

6.3 How Redis removes expired keys

  • Lazy: when a key is accessed, Redis checks it and deletes it if expired.
  • Active: periodically, Redis samples (randomly checks) keys that have a TTL and deletes the expired ones.

So an expired key may not free memory immediately, but you will never be able to read it. With replicas, the master decides expiration and sends a DEL (delete) command to replicas (and writes it to the AOF).

6.4 TTL vs eviction when RAM is full

Eviction means Redis deleting keys on its own because memory is full. It is different from TTL (deleting because time ran out). When memory hits maxmemory, Redis follows maxmemory-policy. Both are settings in redis.conf, not commands:

CONFIG · redis.conf
maxmemory 2gb                    # the RAM limit
maxmemory-policy allkeys-lru     # what to delete when the limit is reached
  • noeviction (default): rejects new writes with an error.
  • allkeys-lru: evicts the Least Recently Used keys (the ones not touched for the longest time) across everything. Good for pure caches.
  • volatile-lru / volatile-ttl: evicts only among keys that have a TTL ("volatile" = has an expiry). Good when cache and must-keep data share one instance.

6.5 Choosing a TTL

Data typeSuggested TTLWhy
OTP / verification codes (One-Time Password: the 6-digit code sent by SMS/email)1 to 5 minutesA code that lives too long is a security risk
Rate-limit countersExactly the window length (1 second, 1 minute...)The window is the period you count in (see 5.4). TTL = window length makes the counter reset exactly when a new window starts. Too short lets users exceed the limit; too long blocks them longer than intended
Sessions15 to 30 minutes, renewed on activityLogs out idle users, but active users stay logged in
Rarely changing cache (categories, config)A few hours to 1 dayData rarely changes, so a long TTL saves many DB reads
Frequently changing cache (price, stock)A few seconds to a few minutesWrong data is costly, so keep it fresh
Cached nulls (anti-penetration)30 seconds to 2 minutesShort, because the record may be created soon

Longer TTL saves more DB load but makes data staler. Pick based on how much staleness the business can tolerate.

6.6 Cache avalanche: avoid simultaneous expiry

If many keys are loaded together with the same TTL, they expire together and all requests hit the DB at once (a cache avalanche). Fix it by adding a random extra time, called jitter, to each TTL:

JAVA CODE · Spring Data Redis
long ttl = 600 + ThreadLocalRandom.current().nextInt(0, 120); // 10 min + 0~2 min
redisTemplate.opsForValue().set(key, value, ttl, TimeUnit.SECONDS);  // = SET key value EX ttl

ThreadLocalRandom is Java's random-number generator. nextInt(0, 120) gives a random whole number from 0 to 119, so each key lives between 600 and 719 seconds and they no longer expire at the same moment.

6.7 Per-cache TTL in Spring

Different caches often need different TTLs. In Spring you define them once in a configuration class (@Bean marks a method whose result Spring manages for you):

JAVA CODE · Spring Boot configuration
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory cf) {
    RedisCacheConfiguration base = RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofMinutes(10));                 // default TTL: 10 minutes

    return RedisCacheManager.builder(cf)
        .cacheDefaults(base)
        .withCacheConfiguration("categories", base.entryTtl(Duration.ofHours(6)))    // this cache: 6 hours
        .withCacheConfiguration("stock",      base.entryTtl(Duration.ofSeconds(30))) // this cache: 30 seconds
        .build();
}

The names "categories" and "stock" are the same cache names you put in @Cacheable(value = "...") (see 5.1). Duration.ofMinutes(10) is just Java's way of writing "10 minutes".

7. Summary

TopicKey takeaway
What it isIn-memory NoSQL key-value database, operated by commands instead of SQL
DeploymentStandalone, then Sentinel (HA), then Cluster (scale data)
PersistenceRDB for fast backup/restore, AOF for durability; use both for important data
When neededDB overloaded by repeated reads, real-time speed, or shared state across instances
CacheJava: @Cacheable, and remember @CacheEvict when data changes
SessionSpring Session shares logins across servers
LockJava: Redisson RLock (Redis idea: SET ... NX PX), always with an expiry
Rate limitRedis: INCR + EXPIRE (or a Lua script); Java: Redisson RRateLimiter
LeaderboardSorted Set (ZINCRBY, ZREVRANGE), O(log N)
TTLAlways set it for caches, add jitter, choose by acceptable staleness

8. Glossary: every unfamiliar term in one place

The "Type" column tells you what kind of thing each term is.

TermTypeMeaning
SET / GETRedis commandStore / read a String value under a key
INCRRedis commandAdd 1 to a numeric key (creates it at 1 if missing). Used for counters
EXPIRE / PEXPIRERedis commandGive an existing key a lifespan, in seconds / milliseconds
TTL / PTTLRedis commandShow remaining lifespan (seconds / milliseconds). -1 = no expiry, -2 = key missing
PERSISTRedis commandRemove a key's lifespan
GETEXRedis commandRead a value and set a new TTL at the same time
DELRedis commandDelete a key
KEYS patternRedis commandList keys matching a pattern. Debugging only, slow on big data
EVALRedis commandRun a Lua script inside Redis
ZADD, ZINCRBY, ZREVRANGE, ZREVRANK, ZSCORERedis commandsSorted Set commands (all start with Z): add, add to score, top N, rank, read score. REV = highest first
HSETRedis commandSet a field inside a Hash (a key that holds several name/value pairs, like a small object)
EX / PXCommand optionUsed with SET: lifespan in seconds (EX) or milliseconds (PX)
NXCommand optionWith SET: only write if the key does Not eXist (used for locks)
KEEPTTLCommand optionWith SET: keep the old TTL instead of wiping it
WITHSCORESCommand optionAlso return each member's score, not just the names
appendfsync everysec, appendonly, saveConfig settingPersistence settings in redis.conf (AOF on/off, flush frequency, RDB snapshot rule)
maxmemory, maxmemory-policyConfig settingRAM limit, and what to delete when it is reached
@Cacheable, @CachePut, @CacheEvictJava annotationSpring labels: use cache / always update cache / remove from cache
@BeanJava annotationMarks a method whose result Spring creates and manages
#idSpring expression"The method parameter named id"
RedisTemplateJava classSpring's main tool for sending commands to Redis; opsForValue() = String commands, opsForZSet() = Sorted Set commands
RLock, RRateLimiterJava class (Redisson)Ready-made distributed lock / rate limiter
KEYS[1], ARGV[1]LuaInside a Lua script: the 1st key and the 1st extra argument you passed to EVAL
WindowConceptThe period of time over which requests are counted (e.g. 1 minute for "100 per minute")
Fixed window / Sliding window / Token bucketConceptThree ways to rate-limit: count in fixed blocks of time / count over a moving period / spend tokens that refill steadily
OTPConceptOne-Time Password: a short-lived code (e.g. 6 digits by SMS) used once
AtomicConceptSeveral steps executed as one indivisible unit; nothing can happen in between
Lua scriptConceptA small script that runs inside Redis, which makes multi-step logic atomic
O(log N)ConceptSpeed notation: when data grows a lot, the time grows only slightly (1 million items = about 20 steps)
TTLConceptTime To Live: how long a key lives before Redis deletes it
Eviction / LRUConceptRedis deleting keys because RAM is full / choosing the least recently used ones
JitterConceptA random extra amount added to TTLs so keys don't all expire together
Cache hit / missConceptThe data was found in the cache / not found, so the DB had to be queried
Cache avalancheConceptMany keys expire at the same moment and all requests hit the DB at once
Cache penetrationConceptRepeated requests for keys that don't exist, which always reach the DB
Stale dataConceptOutdated data (cache still shows the old value after the DB changed)
HA / failoverConceptHigh availability (stays up when a server fails) / automatic switch to a backup server
Shard / hash slotConceptA piece of the data split across servers in Cluster mode; Redis has 16,384 slots that are distributed among shards
SerializableConceptCan be converted to bytes so it can be stored or sent over a network
HTTP 429ConceptStandard "Too Many Requests" response code

Conclusion

Redis shines in speed and its variety of data structures. It usually acts as a cache and real-time layer next to your primary database rather than replacing it. Choose the deployment model based on availability needs and data size, combine RDB + AOF when durability matters, and always set a sensible TTL so your cache stays lean, data stays reasonably fresh, and your system doesn't collapse from an avalanche.

Most importantly: use Redis only when you have a real performance or distributed-architecture problem to solve, because it always comes with infrastructure cost and operational complexity.

Redis A–Z, Java & TTL: Tổng quan

Hướng dẫn ngắn gọn về Redis: Redis là gì, cách triển khai, cách lưu dữ liệu bền vững, khi nào thực sự cần dùng, cách dùng trong Java và cơ chế TTL hoạt động ra sao. Mọi khối mã đều có nhãn là một trong những loại lệnh Redis, mã Java hay file cấu hình.

English version

Thứ Hai, 26 tháng 7, 2021

Creating a Batch Service

To start from scratch, move on to Starting with Spring Initializr.

To skip the basics, do the following:

When you finish, you can check your results against the code in gs-batch-processing/complete.

Business Data

Typically, your customer or a business analyst supplies a spreadsheet. For this simple example, you can find some made-up data in src/main/resources/sample-data.csv:

Jill,Doe
Joe,Doe
Justin,Doe
Jane,Doe
John,Doe

This spreadsheet contains a first name and a last name on each row, separated by a comma. This is a fairly common pattern that Spring can handle without customization.

Spring batch introduction

Spring Batch is a lightweight, comprehensive batch framework designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch builds upon the characteristics of the Spring Framework that people have come to expect (productivity, POJO-based development approach, and general ease of use), while making it easy for developers to access and leverage more advance enterprise services when necessary. Spring Batch is not a scheduling framework. There are many good enterprise schedulers (such as Quartz, Tivoli, Control-M, etc.) available in both the commercial and open source spaces. It is intended to work in conjunction with a scheduler, not replace a scheduler. 

Spring Batch is also a minimalistic framework to run batch processing applications. It provides reusable functions that are essential in processing large volumes of records, including logging/tracing, transaction management, job processing statistics, job restart, skip, and resource management. It also provides more advanced technical services and features that will enable extremely high-volume and high-performance batch jobs through optimization and partitioning techniques. Simple as well as complex, high-volume batch jobs can leverage the framework in a highly scalable manner to process significant volumes of information.

Spring Batch provides reusable functions that are essential in processing large volumes of records, including logging/tracing, transaction management, job processing statistics, job restart, skip, and resource management. It also provides more advanced technical services and features that enable extremely high-volume and high performance batch jobs through optimization and partitioning techniques. Spring Batch can be used in both simple use cases (such as reading a file into a database or running a stored procedure) as well as complex, high volume use cases (such as moving high volumes of data between databases, transforming it, and so on). High-volume batch jobs can leverage the framework in a highly scalable manner to process significant volumes of information.

Thứ Bảy, 24 tháng 7, 2021

What is backbase

🇻🇳 This article is also available in Vietnamese: Backbase là gì?

What are Digital Banking Platforms (DBP)?

A digital banking platform (DBP) enables a bank to begin the transformational process of becoming a truly digital bank that is ecosystem-centric. A DBP also enables banks to achieve business optimization. However, that is not the end state. For banks seeking only business optimization as the goal of their digital banking strategy, a digital banking multichannel solution will meet those needs.

Backbase là gì?

🇬🇧 Bài viết này cũng có bản tiếng Anh: What is Backbase?

Nền tảng ngân hàng số (Digital Banking Platform – DBP) là gì?

Nền tảng ngân hàng số (DBP) giúp ngân hàng bắt đầu quá trình chuyển đổi để trở thành một ngân hàng số thực thụ, lấy hệ sinh thái làm trung tâm. DBP cũng giúp ngân hàng tối ưu hóa hoạt động kinh doanh. Tuy nhiên, đó chưa phải là đích đến cuối cùng. Với những ngân hàng chỉ đặt mục tiêu tối ưu hóa kinh doanh trong chiến lược ngân hàng số, một giải pháp ngân hàng số đa kênh (multichannel) là đã đáp ứng đủ nhu cầu.

Thứ Ba, 2 tháng 3, 2021

Beginning Amazon DynamoDB

What Is Amazon DynamoDB?

Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. 

NoSQL is a term used to describe nonrelational database systems that are highly available, scalable, and optimized for high performance. Instead of the relational model, NoSQL databases (like DynamoDB) use alternate models for data management, such as key-value pairs or document storage. For more information, see http://aws.amazon.com/nosql.

Thứ Ba, 27 tháng 10, 2020

MyBatis introduction

 MyBatis is a Java persistence framework that couples objects with stored procedures or SQL statements using an XML descriptor or annotations.

MyBatis is free software that is distributed under the Apache License 2.0.

MyBatis is a fork of iBATIS 3.0 and is maintained by a team that includes the original creators of iBATIS. 

MyBatis is a first class persistence framework with support for custom SQL, stored procedures and advanced mappings. MyBatis eliminates almost all of the JDBC code and manual setting of parameters and retrieval of results. MyBatis can use simple XML or Annotations for configuration and map primitives, Map interfaces and Java POJOs (Plain Old Java Objects) to database records

Chủ Nhật, 9 tháng 8, 2020

Beginning playframework

What is Play?

Play is a high-productivity Java and Scala web application framework that integrates components and APIs for modern web application development. Play was developed by web developers for web application development.

Play uses Model-View-Controller (MVC) architecture so that It is familiar and easy to learn. Play is a full-stack framework so that Play includes all the components you need to build Web Applications and REST services, such as an integrated HTTP server, form handling, Cross-Site Request Forgery (CSRF) protection, a powerful routing mechanism, I18n support, and more.

Play’s lightweight, stateless, web-friendly architecture uses Akka and Akka Streams under the covers to provide predictable and minimal resource consumption (CPU, memory, threads).

Play is non-opinionated about database access, and integrates with many object relational mapping (ORM) layers. It supports Anorm, Slick, and JPA out of the box, but many customers use NoSQL or other ORMs.

Thứ Hai, 6 tháng 7, 2020

Doing microservices with JHipster

Today many companies are developing applications using Microservices, and Microservices with spring boot is chosen by many big companies in Vietnam.
In JHipster framework, Microservices is also supported. JHipster is a free and open-source application generator used to quickly develop modern web applications and Microservices using Angular or React (JavaScript library) and the Spring Framework.

Some technologies and tools are:

  • Yeoman, a front-end scaffolding tool
  • Spring Boot
  • Angular 8, ReactJS: frontend Javascript frameworks.
  • Swagger, for API documentation
  • Maven, Npm, Yarn, Gulp and Bower are dependency managers and build tools
  • Jasmine, Protractor, Cucumber and Gatling are test frameworks
  • Liquibase is for database versioning

We need to  install Java 8, Git (version control system), NodeJS, Yeoman, Yarn and may be Gulp and Bower also on the computer.

Microservices vs Monolithic architecture

The first question JHipster will ask you is the kind of application you want to generate. You have the choice between two architecture styles:
  • A “monolithic” architecture uses a single, one-size-fits-all application, which contains both the front-end code, and the back-end Spring Boot code.
  • A “microservices” architecture splits the front-end and the back-end, so that it’s easier for your application to scale and survive infrastructure issues.
A “monolithic” application is much easier to work on, so if you don’t have any specific requirements, this is the option we recommend, and our default option.
However, A “monolithic” application is still an Spring Boot application with Microservices support.

Microservices architecture overview

The JHipster microservices architecture works in the following way:
  • A gateway is a JHipster-generated application (using application type microservice gateway when you generate it) that handles Web traffic, and serves an Angular/React application. There can be several different gateways, if you want to follow the Backends for Frontends pattern, but that’s not mandatory.
  • Traefik is a modern HTTP reverse proxy and load balancer that can work with a gateway.
  • The JHipster Registry is a runtime application on which all applications registers and get their configuration from. It also provides runtime monitoring dashboards.
  • Consul is a service discovery service, as well as a key/value store. It can be used as an alternative to the JHipster Registry.
  • JHipster UAA is a JHipster-based User Authentication and Authorization system, which uses the OAuth2 protocol.
  • Microservices are JHipster-generated applications (using application type microservice application when you generate them), that handle REST requests. They are stateless, and several instances of them can be launched in parallel to handle heavy loads.
  • The JHipster Console is a monitoring & alerting console, based on the ELK stack.

In the diagram below, the green components are specific to your application and the blue components provide its underlying infrastructure.

From above picture, we can see that Eureka Server has been wrapped into Jhipster Registry, because the standard architecture of Eureka Server is something like following:

Docker installation

Guide to install docker on windows: https://docs.docker.com/toolbox/toolbox_install_windows/, https://github.com/docker/toolbox/releases
After installation, click on shortcut on desktop of computer to start docker

Then the terminal will appear with messages

Type the docker run hello-world command and press RETURN.

In the first times, It will show errors and then download hello-world example. If you run that command in the second times, It will show above messages. That means the installation of docker is okay.

Install Compose on Windows desktop systems
Docker Desktop for Windows and Docker Toolbox already include Compose along with other Docker apps, so most Windows users do not need to install Compose separately. Docker install instructions for these are here:


Reference:

Chủ Nhật, 5 tháng 7, 2020

SSO java-servlet-application-with-keycloak

There are some concepts relating to SSO - single sign on in software applications.

What is OpenID?

OpenID allows you to use an existing account to sign in to multiple websites, without needing to create new passwords.
You may choose to associate information with your OpenID that can be shared with the websites you visit, such as a name or email address. With OpenID, you control how much of that information is shared with the websites you visit.
With OpenID, your password is only given to your identity provider, and that provider then confirms your identity to the websites you visit.  Other than your provider, no website ever sees your password, so you don’t need to worry about an unscrupulous or insecure website compromising your identity.
So when talking about OpenID it means we are talking about authentication topics.

Thứ Bảy, 4 tháng 7, 2020

Spring Security Overview

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements

Thứ Bảy, 9 tháng 5, 2020

Angular 2 with ZK

With the emerging of reactjs and angular2, zk and other old ui java frameworks are standing before of going to history library but now angular2 has been integrated into zk and make it having more custom chosen for users so that zk framework is still used for maintainance and new java projects.

Angular 2 is integrated in zk by using  client command binding to communicate with a Java ViewModel at the server-side.

Thứ Tư, 26 tháng 6, 2019

Jakarta EE and JSF 2.x

Jakarta EE

In September 2017, Oracle announced its intention to transition Java EE to the Eclipse Foundation. Java EE has since been rebranded to Jakarta EE, and JSF 2.3 (Eclipse Mojarra) has been adopted for continuation. The next major release of the JSF specification will be Eclipse Mojarra 3.0. (source from JavaWorld).

Chủ Nhật, 26 tháng 5, 2019

Oracle SQL căn bản P2

1> Execute a function that is defined in a package

Question: How can I execute a function that is defined in a package using Oracle/PLSQL?
Answer: To execute a function that is defined in a package, you'll have to prefix the function name with the package name.
package_name.function_name (parameter1, parameter2, ... parameter_n)
You can execute a function a few different ways.

Thứ Bảy, 30 tháng 3, 2019

Create a backend for frontend application architecture

A Backend for Frontend (BFF) architecture can be used to create backends for client-facing mobile or web apps. BFF’s can help support an application with multiple clients while at the same time moving the system into a less-coupled state than a monolith system. This code pattern helps teams iterate features faster and have control over the backends for mobile apps without affecting the experience for a corresponding mobile or web app.

Chủ Nhật, 9 tháng 9, 2018

Beginning elasticsearch

1. Elasticsearch concepts

What Wikipedia says

Elasticsearch is a search engine based on Lucene. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. Elasticsearch is developed in Java and is released as open source under the terms of the Apache License. Official clients are available in Java, .NET (C#), PHP, Python, Apache Groovy, Ruby and many other languages. According to the DB-Engines ranking, Elasticsearch is the most popular enterprise search engine, followed by Apache Solr, also based on Lucene.
Source: Wikipedia – Elasticsearch

Definition from the Elastic site

Elasticsearch is a real-time distributed search and analytics engine. It allows you to explore your data at a speed and at a scale never before possible. It is used for full-text search, structured search, analytics, and all three in combination.
Source: Elastic – Getting Started

Real-world examples:

  • Wikipedia uses Elasticsearch for full-text search with highlighted snippets, plus search-as-you-type and did-you-mean suggestions.
  • The Guardian combines visitor logs with social-network data to give editors real-time feedback on the public's response to new articles.
  • Stack Overflow combines full-text search with geolocation queries and uses more-like-this to find related questions and answers.
  • GitHub uses Elasticsearch to query 130 billion lines of code.

Thứ Bảy, 8 tháng 9, 2018

React.js and Spring Data REST - Basic Features

Spring Data REST provides backend functionality
React has sophisticated features to build an easy-to-grok UI.
  • Spring Data REST provides a fast way to build hypermedia-powered repositories.
  • React is Facebook’s solution to efficient, fast, and easy-to-use views in the land of JavaScript.

Thứ Hai, 3 tháng 9, 2018

Java Concurrency

1. Java Concurrency from docs.oracle.com

Computer users take it for granted that their systems can do more than one thing at a time. They assume that they can continue to work in a word processor, while other applications download files, manage the print queue, and stream audio. Even a single application is often expected to do more than one thing at a time. For example, that streaming audio application must simultaneously read the digital audio off the network, decompress it, manage playback, and update its display. Even the word processor should always be ready to respond to keyboard and mouse events, no matter how busy it is reformatting text or updating the display. Software that can do such things is known as concurrent software.
The Java platform is designed from the ground up to support concurrent programming, with basic concurrency support in the Java programming language and the Java class libraries. Since version 5.0, the Java platform has also included high-level concurrency APIs. This lesson introduces the platform's basic concurrency support and summarizes some of the high-level APIs in the java.util.concurrent packages.

Database normalization Introduction

Database normalization is the process of restructuring a relational database in accordance with a series of so-called normal forms in order to reduce data redundancyand improve data integrity. It was first proposed by Edgar F. Codd as an integral part of his relational model.
Normalization entails organizing the columns (attributes) and tables (relations) of a database to ensure that their dependencies are properly enforced by database integrity constraints. It is accomplished by applying some formal rules either by a process of synthesis (creating a new database design) or decomposition (improving an existing database design).

=> quá trình chuẩn hóa DB sẽ áp dụng 1 số luật (các dạng chuẩn) để thiết kế các bảng cơ sở dữ liệu sao cho có thể giảm thiếu tối đa dư thừa dữ liệu, sự chính xác của truy vấn dữ liệu, tăng performance truy xuất DB...

PHỔ BIẾN

NHÃN

LƯỢT XEM