private void insertStringRecordsWithLeaderCache(
      List<String> deviceIds,
      List<Long> times,
      List<List<String>> measurementsList,
      List<List<String>> valuesList,
      boolean isAligned)
      throws IoTDBConnectionException, StatementExecutionException {
    Map<SessionConnection, TSInsertStringRecordsReq> recordsGroup = new HashMap<>();
    for (int i = 0; i < deviceIds.size(); i++) {
      final SessionConnection connection = getSessionConnection(deviceIds.get(i));
      TSInsertStringRecordsReq request =
          recordsGroup.getOrDefault(connection, new TSInsertStringRecordsReq());
      request.setIsAligned(isAligned);
      try {
        filterAndUpdateTSInsertStringRecordsReq(
            request, deviceIds.get(i), times.get(i), measurementsList.get(i), valuesList.get(i));
        recordsGroup.putIfAbsent(connection, request);
      } catch (NoValidValueException e) {
        logger.warn(
            ALL_VALUES_ARE_NULL,
            deviceIds.get(i),
            times.get(i),
            measurementsList.get(i).toString());
      }
    }
    if (recordsGroup.size() == 1) {
      insertOnce(recordsGroup, SessionConnection::insertRecords);
    } else {
      insertByGroup(recordsGroup, SessionConnection::insertRecords);
    }
  }
Insert aligned multiple rows, which can reduce the overhead of network. This method is just
like jdbc executeBatch, we pack some insert request in batch and send them to server. If you
want improve your performance, please see insertTablet method

<p>Each row is independent, which could have different prefixPath, time, number of
subMeasurements

@see Session#insertTablet(Tablet)
iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java