Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize: refactor the redis lock string to hash #3016

Merged
merged 21 commits into from
Sep 3, 2020
Merged

optimize: refactor the redis lock string to hash #3016

merged 21 commits into from
Sep 3, 2020

Conversation

lightClouds917
Copy link
Contributor

@lightClouds917 lightClouds917 commented Aug 14, 2020

Ⅰ. Describe what this PR did

redis lock data structor ,use hash to replace string

Ⅱ. Does this pull request fix one issue?

fixes #3008

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

@codecov-commenter
Copy link

codecov-commenter commented Aug 14, 2020

Codecov Report

Merging #3016 into develop will increase coverage by 0.03%.
The diff coverage is 65.82%.

Impacted file tree graph

@@              Coverage Diff              @@
##             develop    #3016      +/-   ##
=============================================
+ Coverage      50.39%   50.43%   +0.03%     
- Complexity      3092     3100       +8     
=============================================
  Files            599      599              
  Lines          19531    19488      -43     
  Branches        2412     2360      -52     
=============================================
- Hits            9843     9829      -14     
+ Misses          8697     8644      -53     
- Partials         991     1015      +24     
Impacted Files Coverage Δ Complexity Δ
...ommon/src/main/java/io/seata/common/Constants.java 50.00% <ø> (ø) 1.00 <0.00> (ø)
...o/seata/server/storage/redis/lock/RedisLocker.java 63.96% <65.82%> (+24.12%) 19.00 <10.00> (+7.00)
...obuf/convertor/BranchRegisterRequestConvertor.java 90.47% <0.00%> (-9.53%) 3.00% <0.00%> (ø%)
...otobuf/convertor/BranchReportRequestConvertor.java 90.90% <0.00%> (-9.10%) 3.00% <0.00%> (ø%)
...obuf/convertor/BranchRollbackRequestConvertor.java 92.00% <0.00%> (-8.00%) 3.00% <0.00%> (ø%)
...otobuf/convertor/GlobalBeginResponseConvertor.java 92.59% <0.00%> (-7.41%) 3.00% <0.00%> (ø%)
...otobuf/convertor/GlobalCommitRequestConvertor.java 93.75% <0.00%> (-6.25%) 3.00% <0.00%> (ø%)
...otobuf/convertor/GlobalStatusRequestConvertor.java 93.75% <0.00%> (-6.25%) 3.00% <0.00%> (ø%)
...obuf/convertor/GlobalRollbackRequestConvertor.java 93.75% <0.00%> (-6.25%) 3.00% <0.00%> (ø%)
...protobuf/convertor/RegisterTMRequestConvertor.java 94.73% <0.00%> (-5.27%) 3.00% <0.00%> (ø%)
... and 29 more

@funky-eyes
Copy link
Contributor

funky-eyes commented Aug 14, 2020

list change hash xid branch1 branch1_info branch2 branch2_info.....
string change hash lock_table rawlock1 branch1_info rawlock2 branch2_info

del:
hgetall xid
branch1->branch1_info json.get("rawlock")->rawlock1
hdel lock_table rawlock1

competition lock:
hsetnx lock_table rawlock1 branch1_info

reentrant lock:
hmget lock_table rawlock1
rawlock1->branch1 json.get(xid).eq(xid)

lockMap.put(TABLE_NAME, value.getTableName());
lockMap.put(ROW_KEY, value.getRowKey());
lockMap.put(PK, value.getPk());
pipeline.hmset(key, lockMap);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cannot play the role of competition lock

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

@lightClouds917 lightClouds917 changed the title refactor:the redis lock string to hash [WIP]refactor:the redis lock string to hash Aug 15, 2020
@funky-eyes funky-eyes added the TC/store store mode label Aug 15, 2020
@lightClouds917 lightClouds917 changed the title [WIP]refactor:the redis lock string to hash refactor:the redis lock string to hash Aug 18, 2020
@lightClouds917
Copy link
Contributor Author

The data structure of redis lock like this now :

image

Copy link
Contributor

@funky-eyes funky-eyes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please check my message

String key = readyKeys.get(i);
if (result != 1) {
status = result;
if (partitions.contains(FAILED)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partitions.get(i).contains

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

if (successSet.size() > 0) {
Pipeline pipeline2 = jedis.pipelined();
successSet.forEach(locKey ->
pipeline2.hdel(locKey, XID, TRANSACTION_ID, BRANCH_ID, RESOURCE_ID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

del successSet. toArray (new String[0])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished


Pipeline pipeline1 = jedis.pipelined();
needLockKeys.stream().forEachOrdered(
needLockKey -> pipeline1.hmget(needLockKey, XID, TABLE_NAME, PK, BRANCH_ID));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only need to xid

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

readyKeys.add(key);
});
List<Object> results = pipeline.syncAndReturnAll();
for (int i = 0; i < results.size(); i++) {
Long result = (long)results.get(i);
List<Integer> results2 = (List<Integer>) (List) results;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List< Integer > results = (List) (List) pipeline.syncAndReturnAll();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

needReleaseKeys.stream()
.forEach(key -> pipelined.hmget(key, XID, TABLE_NAME, PK, BRANCH_ID));
List<Object> existedObjs = pipelined.syncAndReturnAll();
List<List<String>> existedLockInfos = (List<List<String>>) (List) existedObjs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the lock can only be actively unlocked by the owner without having to retrieve it again

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

pipeline.sync();
Pipeline pipelined = jedis.pipelined();
needReleaseKeys.stream()
.forEach(key -> pipelined.hmget(key, XID, TABLE_NAME, PK, BRANCH_ID));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only need to xid

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished


Pipeline pipelined1 = jedis.pipelined();
needReleaseKeys.stream().forEach(key ->
pipelined1.hdel(key, XID, TRANSACTION_ID, BRANCH_ID, RESOURCE_ID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

del needReleaseKeys. toArray (new String[0])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

String[] keys = rowKeyStr.split(SEMICOLON);
Arrays.asList(keys).stream().forEach(rowKey -> {
if (StringUtils.isNotEmpty(rowKey)) {
pipelined.hdel(rowKey, XID, TRANSACTION_ID, BRANCH_ID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

del rowkey

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

}
});
} else {
pipelined.hdel(rowKeyStr, XID, TRANSACTION_ID, BRANCH_ID, RESOURCE_ID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

del rowkey

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

Pipeline pipeline = jedis.pipelined();
lockKeys.stream().forEach(key -> pipeline.hget(key, XID));
List<Object> existedRowLockXid = pipeline.syncAndReturnAll();
List<String> existedXids = (List<String>) (List) existedRowLockXid;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List existedXids = (List) (List) pipeline.syncAndReturnAll();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

String xidLockKey = buildXidLockKey(needLockXid);
StringJoiner lockKeysString = new StringJoiner(SEMICOLON);
needLockKeys.stream().forEach(lockKey -> lockKeysString.add(lockKey));
jedis.hsetnx(xidLockKey, branchId.toString(), lockKeysString.toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hset enough

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

Pipeline pipeline = jedis.pipelined();
lockKeys.stream().forEach(key -> pipeline.hget(key, XID));
List<String> existedXids = (List<String>) (List) pipeline.syncAndReturnAll();
return existedXids.stream().allMatch(existedXid -> xid.equals(existedXid));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please pay attention to this problem: list All elements are null
existedXids.size>0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

@@ -60,131 +82,139 @@
*/
public RedisLocker() {
logQueryLimit =
ConfigurationFactory.getInstance().getInt(ConfigurationKeys.STORE_REDIS_QUERY_LIMIT, DEFAULT_QUERY_LIMIT);
ConfigurationFactory.getInstance()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need the logQueryLimit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

@funky-eyes funky-eyes added the module/server server module label Aug 19, 2020
Copy link
Contributor

@funky-eyes funky-eyes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@ph3636 ph3636 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the structure is not compatible
LGTM

/** the start time of transaction */
public static final String START_TIME = "start-time";
/**
* The constant ;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be completed or deleted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

@@ -15,23 +15,21 @@
*/
package io.seata.server.storage.redis.lock;

import static io.seata.common.Constants.SEMICOLON;

import com.google.common.collect.Lists;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be placed below

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seemed that the java package was on the top

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seemed that the java package was on the top

finished

locks =
locks.stream().filter(LambdaUtils.distinctByKey(LockDO::getRowKey)).collect(Collectors.toList());
List<LockDO> needLockDOS = convertToLockDO(rowLocks);
if (needLockDOS.size() >= 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove equal to

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning here is the same as before, so be it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning here is the same as before, so be it

finished

return DEFAULT_REDIS_SEATA_LOCK_XID_PREFIX + xid;
}

private String getLockKey(String rowKey) {
private String buildLockKey(String rowKey) {
return DEFAULT_REDIS_SEATA_LOCK_PREFIX + rowKey;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the names of these two keys for structure error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the names of these two keys for structure error

finished

@funky-eyes funky-eyes added this to the 1.4.0 milestone Aug 28, 2020
Copy link
Contributor

@l81893521 l81893521 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for @ph3636

@funky-eyes funky-eyes changed the title refactor:the redis lock string to hash optimize: refactor the redis lock string to hash Sep 3, 2020
@funky-eyes funky-eyes merged commit fc0c9ce into apache:develop Sep 3, 2020
l81893521 pushed a commit to l81893521/seata that referenced this pull request Oct 22, 2020
hicf pushed a commit to hicf/seata that referenced this pull request Nov 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module/server server module TC/store store mode
Projects
None yet
Development

Successfully merging this pull request may close these issues.

refactor the redis data structure
5 participants